From 5b1a1bf5bfc520248285b036672146122dd2a815 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 20 Mar 2009 10:32:24 +0000 Subject: Make Active Model test suite similar to Active Record --- activemodel/test/cases/helper.rb | 38 +++ activemodel/test/cases/observing_test.rb | 121 ++++++++ activemodel/test/cases/state_machine/event_test.rb | 49 ++++ .../test/cases/state_machine/machine_test.rb | 43 +++ activemodel/test/cases/state_machine/state_test.rb | 72 +++++ .../cases/state_machine/state_transition_test.rb | 84 ++++++ activemodel/test/cases/state_machine_test.rb | 312 +++++++++++++++++++++ activemodel/test/config.rb | 3 + activemodel/test/fixtures/fixture_database.sqlite3 | Bin 0 -> 2048 bytes activemodel/test/fixtures/topics.yml | 41 +++ activemodel/test/observing_test.rb | 121 -------- activemodel/test/schema.rb | 22 ++ activemodel/test/state_machine/event_test.rb | 49 ---- activemodel/test/state_machine/machine_test.rb | 43 --- activemodel/test/state_machine/state_test.rb | 72 ----- .../test/state_machine/state_transition_test.rb | 84 ------ activemodel/test/state_machine_test.rb | 312 --------------------- activemodel/test/test_helper.rb | 21 -- 18 files changed, 785 insertions(+), 702 deletions(-) create mode 100644 activemodel/test/cases/helper.rb create mode 100644 activemodel/test/cases/observing_test.rb create mode 100644 activemodel/test/cases/state_machine/event_test.rb create mode 100644 activemodel/test/cases/state_machine/machine_test.rb create mode 100644 activemodel/test/cases/state_machine/state_test.rb create mode 100644 activemodel/test/cases/state_machine/state_transition_test.rb create mode 100644 activemodel/test/cases/state_machine_test.rb create mode 100644 activemodel/test/config.rb create mode 100644 activemodel/test/fixtures/fixture_database.sqlite3 create mode 100644 activemodel/test/fixtures/topics.yml delete mode 100644 activemodel/test/observing_test.rb create mode 100644 activemodel/test/schema.rb delete mode 100644 activemodel/test/state_machine/event_test.rb delete mode 100644 activemodel/test/state_machine/machine_test.rb delete mode 100644 activemodel/test/state_machine/state_test.rb delete mode 100644 activemodel/test/state_machine/state_transition_test.rb delete mode 100644 activemodel/test/state_machine_test.rb delete mode 100644 activemodel/test/test_helper.rb (limited to 'activemodel/test') diff --git a/activemodel/test/cases/helper.rb b/activemodel/test/cases/helper.rb new file mode 100644 index 0000000000..6465f4e61f --- /dev/null +++ b/activemodel/test/cases/helper.rb @@ -0,0 +1,38 @@ +$:.unshift(File.dirname(__FILE__) + '/../../lib') +$:.unshift(File.dirname(__FILE__) + '/../../../activerecord/lib') +$:.unshift(File.dirname(__FILE__) + '/../../../activesupport/lib') + +require 'config' +require 'active_model' + +require 'active_record' +require 'logger' +ActiveRecord::Base.logger = Logger.new("debug.log") + +class SqliteError < StandardError +end + +# Setup database connection +db_file = "#{FIXTURES_ROOT}/fixture_database.sqlite3" +ActiveRecord::Base.configurations = { ActiveRecord::Base.name => { :adapter => 'sqlite3', :database => db_file, :timeout => 5000 } } +unless File.exist?(db_file) + puts "SQLite3 database not found at #{db_file}. Rebuilding it." + sqlite_command = %Q{sqlite3 "#{db_file}" "create table a (a integer); drop table a;"} + puts "Executing '#{sqlite_command}'" + raise SqliteError.new("Seems that there is no sqlite3 executable available") unless system(sqlite_command) +end +ActiveRecord::Base.establish_connection(ActiveRecord::Base.name) + +# Show backtraces for deprecated behavior for quicker cleanup. +ActiveSupport::Deprecation.debug = true + +require 'rubygems' +require 'test/unit' +gem 'mocha', '>= 0.9.5' +require 'mocha' + +begin + require 'ruby-debug' + Debugger.start +rescue LoadError +end diff --git a/activemodel/test/cases/observing_test.rb b/activemodel/test/cases/observing_test.rb new file mode 100644 index 0000000000..421ac4b4f8 --- /dev/null +++ b/activemodel/test/cases/observing_test.rb @@ -0,0 +1,121 @@ +require 'cases/helper' + +class ObservedModel < ActiveModel::Base + class Observer + end +end + +class FooObserver < ActiveModel::Observer + class << self + public :new + end + + attr_accessor :stub + + def on_spec(record) + stub.event_with(record) if stub + end +end + +class Foo < ActiveModel::Base +end + +class ObservingTest < ActiveModel::TestCase + def setup + ObservedModel.observers.clear + end + + test "initializes model with no cached observers" do + assert ObservedModel.observers.empty?, "Not empty: #{ObservedModel.observers.inspect}" + end + + test "stores cached observers in an array" do + ObservedModel.observers << :foo + assert ObservedModel.observers.include?(:foo), ":foo not in #{ObservedModel.observers.inspect}" + end + + test "flattens array of assigned cached observers" do + ObservedModel.observers = [[:foo], :bar] + assert ObservedModel.observers.include?(:foo), ":foo not in #{ObservedModel.observers.inspect}" + assert ObservedModel.observers.include?(:bar), ":bar not in #{ObservedModel.observers.inspect}" + end + + test "instantiates observer names passed as strings" do + ObservedModel.observers << 'foo_observer' + FooObserver.expects(:instance) + ObservedModel.instantiate_observers + end + + test "instantiates observer names passed as symbols" do + ObservedModel.observers << :foo_observer + FooObserver.expects(:instance) + ObservedModel.instantiate_observers + end + + test "instantiates observer classes" do + ObservedModel.observers << ObservedModel::Observer + ObservedModel::Observer.expects(:instance) + ObservedModel.instantiate_observers + end + + test "passes observers to subclasses" do + FooObserver.instance + bar = Class.new(Foo) + assert_equal Foo.count_observers, bar.count_observers + end +end + +class ObserverTest < ActiveModel::TestCase + def setup + ObservedModel.observers = :foo_observer + FooObserver.models = nil + end + + test "guesses implicit observable model name" do + assert_equal 'Foo', FooObserver.observed_class_name + end + + test "tracks implicit observable models" do + instance = FooObserver.new + assert instance.send(:observed_classes).include?(Foo), "Foo not in #{instance.send(:observed_classes).inspect}" + assert !instance.send(:observed_classes).include?(ObservedModel), "ObservedModel in #{instance.send(:observed_classes).inspect}" + end + + test "tracks explicit observed model class" do + old_instance = FooObserver.new + assert !old_instance.send(:observed_classes).include?(ObservedModel), "ObservedModel in #{old_instance.send(:observed_classes).inspect}" + FooObserver.observe ObservedModel + instance = FooObserver.new + assert instance.send(:observed_classes).include?(ObservedModel), "ObservedModel not in #{instance.send(:observed_classes).inspect}" + end + + test "tracks explicit observed model as string" do + old_instance = FooObserver.new + assert !old_instance.send(:observed_classes).include?(ObservedModel), "ObservedModel in #{old_instance.send(:observed_classes).inspect}" + FooObserver.observe 'observed_model' + instance = FooObserver.new + assert instance.send(:observed_classes).include?(ObservedModel), "ObservedModel not in #{instance.send(:observed_classes).inspect}" + end + + test "tracks explicit observed model as symbol" do + old_instance = FooObserver.new + assert !old_instance.send(:observed_classes).include?(ObservedModel), "ObservedModel in #{old_instance.send(:observed_classes).inspect}" + FooObserver.observe :observed_model + instance = FooObserver.new + assert instance.send(:observed_classes).include?(ObservedModel), "ObservedModel not in #{instance.send(:observed_classes).inspect}" + end + + test "calls existing observer event" do + foo = Foo.new + FooObserver.instance.stub = stub + FooObserver.instance.stub.expects(:event_with).with(foo) + Foo.send(:changed) + Foo.send(:notify_observers, :on_spec, foo) + end + + test "skips nonexistent observer event" do + foo = Foo.new + Foo.send(:changed) + Foo.send(:notify_observers, :whatever, foo) + end +end diff --git a/activemodel/test/cases/state_machine/event_test.rb b/activemodel/test/cases/state_machine/event_test.rb new file mode 100644 index 0000000000..2a0ef53a3f --- /dev/null +++ b/activemodel/test/cases/state_machine/event_test.rb @@ -0,0 +1,49 @@ +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 new file mode 100644 index 0000000000..2aa954d80c --- /dev/null +++ b/activemodel/test/cases/state_machine/machine_test.rb @@ -0,0 +1,43 @@ +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 new file mode 100644 index 0000000000..527bfd4c04 --- /dev/null +++ b/activemodel/test/cases/state_machine/state_test.rb @@ -0,0 +1,72 @@ +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 new file mode 100644 index 0000000000..17f9d88be7 --- /dev/null +++ b/activemodel/test/cases/state_machine/state_transition_test.rb @@ -0,0 +1,84 @@ +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 new file mode 100644 index 0000000000..f66299741e --- /dev/null +++ b/activemodel/test/cases/state_machine_test.rb @@ -0,0 +1,312 @@ +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/config.rb b/activemodel/test/config.rb new file mode 100644 index 0000000000..0b577a9936 --- /dev/null +++ b/activemodel/test/config.rb @@ -0,0 +1,3 @@ +TEST_ROOT = File.expand_path(File.dirname(__FILE__)) +FIXTURES_ROOT = TEST_ROOT + "/fixtures" +SCHEMA_FILE = TEST_ROOT + "/schema.rb" diff --git a/activemodel/test/fixtures/fixture_database.sqlite3 b/activemodel/test/fixtures/fixture_database.sqlite3 new file mode 100644 index 0000000000..3847b16aca Binary files /dev/null and b/activemodel/test/fixtures/fixture_database.sqlite3 differ diff --git a/activemodel/test/fixtures/topics.yml b/activemodel/test/fixtures/topics.yml new file mode 100644 index 0000000000..e4c61ce2d8 --- /dev/null +++ b/activemodel/test/fixtures/topics.yml @@ -0,0 +1,41 @@ +first: + id: 1 + title: The First Topic + author_name: David + author_email_address: david@loudthinking.com + written_on: 2003-07-16t15:28:11.2233+01:00 + last_read: 2004-04-15 + bonus_time: 2005-01-30t15:28:00.00+01:00 + content: Have a nice day + approved: false + replies_count: 1 + +second: + id: 2 + title: The Second Topic of the day + author_name: Mary + written_on: 2004-07-15t15:28:00.0099+01:00 + content: Have a nice day + approved: true + replies_count: 0 + parent_id: 1 + type: Reply + +third: + id: 3 + title: The Third Topic of the day + author_name: Nick + written_on: 2005-07-15t15:28:00.0099+01:00 + content: I'm a troll + approved: true + replies_count: 1 + +fourth: + id: 4 + title: The Fourth Topic of the day + author_name: Carl + written_on: 2006-07-15t15:28:00.0099+01:00 + content: Why not? + approved: true + type: Reply + parent_id: 3 diff --git a/activemodel/test/observing_test.rb b/activemodel/test/observing_test.rb deleted file mode 100644 index dc41c9f881..0000000000 --- a/activemodel/test/observing_test.rb +++ /dev/null @@ -1,121 +0,0 @@ -require 'test_helper' - -class ObservedModel < ActiveModel::Base - class Observer - end -end - -class FooObserver < ActiveModel::Observer - class << self - public :new - end - - attr_accessor :stub - - def on_spec(record) - stub.event_with(record) if stub - end -end - -class Foo < ActiveModel::Base -end - -class ObservingTest < ActiveModel::TestCase - def setup - ObservedModel.observers.clear - end - - test "initializes model with no cached observers" do - assert ObservedModel.observers.empty?, "Not empty: #{ObservedModel.observers.inspect}" - end - - test "stores cached observers in an array" do - ObservedModel.observers << :foo - assert ObservedModel.observers.include?(:foo), ":foo not in #{ObservedModel.observers.inspect}" - end - - test "flattens array of assigned cached observers" do - ObservedModel.observers = [[:foo], :bar] - assert ObservedModel.observers.include?(:foo), ":foo not in #{ObservedModel.observers.inspect}" - assert ObservedModel.observers.include?(:bar), ":bar not in #{ObservedModel.observers.inspect}" - end - - test "instantiates observer names passed as strings" do - ObservedModel.observers << 'foo_observer' - FooObserver.expects(:instance) - ObservedModel.instantiate_observers - end - - test "instantiates observer names passed as symbols" do - ObservedModel.observers << :foo_observer - FooObserver.expects(:instance) - ObservedModel.instantiate_observers - end - - test "instantiates observer classes" do - ObservedModel.observers << ObservedModel::Observer - ObservedModel::Observer.expects(:instance) - ObservedModel.instantiate_observers - end - - test "passes observers to subclasses" do - FooObserver.instance - bar = Class.new(Foo) - assert_equal Foo.count_observers, bar.count_observers - end -end - -class ObserverTest < ActiveModel::TestCase - def setup - ObservedModel.observers = :foo_observer - FooObserver.models = nil - end - - test "guesses implicit observable model name" do - assert_equal 'Foo', FooObserver.observed_class_name - end - - test "tracks implicit observable models" do - instance = FooObserver.new - assert instance.send(:observed_classes).include?(Foo), "Foo not in #{instance.send(:observed_classes).inspect}" - assert !instance.send(:observed_classes).include?(ObservedModel), "ObservedModel in #{instance.send(:observed_classes).inspect}" - end - - test "tracks explicit observed model class" do - old_instance = FooObserver.new - assert !old_instance.send(:observed_classes).include?(ObservedModel), "ObservedModel in #{old_instance.send(:observed_classes).inspect}" - FooObserver.observe ObservedModel - instance = FooObserver.new - assert instance.send(:observed_classes).include?(ObservedModel), "ObservedModel not in #{instance.send(:observed_classes).inspect}" - end - - test "tracks explicit observed model as string" do - old_instance = FooObserver.new - assert !old_instance.send(:observed_classes).include?(ObservedModel), "ObservedModel in #{old_instance.send(:observed_classes).inspect}" - FooObserver.observe 'observed_model' - instance = FooObserver.new - assert instance.send(:observed_classes).include?(ObservedModel), "ObservedModel not in #{instance.send(:observed_classes).inspect}" - end - - test "tracks explicit observed model as symbol" do - old_instance = FooObserver.new - assert !old_instance.send(:observed_classes).include?(ObservedModel), "ObservedModel in #{old_instance.send(:observed_classes).inspect}" - FooObserver.observe :observed_model - instance = FooObserver.new - assert instance.send(:observed_classes).include?(ObservedModel), "ObservedModel not in #{instance.send(:observed_classes).inspect}" - end - - test "calls existing observer event" do - foo = Foo.new - FooObserver.instance.stub = stub - FooObserver.instance.stub.expects(:event_with).with(foo) - Foo.send(:changed) - Foo.send(:notify_observers, :on_spec, foo) - end - - test "skips nonexistent observer event" do - foo = Foo.new - Foo.send(:changed) - Foo.send(:notify_observers, :whatever, foo) - end -end diff --git a/activemodel/test/schema.rb b/activemodel/test/schema.rb new file mode 100644 index 0000000000..3f289c63f8 --- /dev/null +++ b/activemodel/test/schema.rb @@ -0,0 +1,22 @@ +ActiveRecord::Schema.define do + create_table :topics, :force => true do |t| + t.string :title + t.string :author_name + t.string :author_email_address + t.datetime :written_on + t.time :bonus_time + t.date :last_read + t.text :content + t.boolean :approved, :default => true + t.integer :replies_count, :default => 0 + t.integer :parent_id + t.string :type + end + + create_table :developers, :force => true do |t| + t.string :name + t.integer :salary, :default => 70000 + t.datetime :created_at + t.datetime :updated_at + end +end diff --git a/activemodel/test/state_machine/event_test.rb b/activemodel/test/state_machine/event_test.rb deleted file mode 100644 index 64dc8c4875..0000000000 --- a/activemodel/test/state_machine/event_test.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'test_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/state_machine/machine_test.rb b/activemodel/test/state_machine/machine_test.rb deleted file mode 100644 index d23c223160..0000000000 --- a/activemodel/test/state_machine/machine_test.rb +++ /dev/null @@ -1,43 +0,0 @@ -require 'test_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/state_machine/state_test.rb b/activemodel/test/state_machine/state_test.rb deleted file mode 100644 index fbf9ce7b0a..0000000000 --- a/activemodel/test/state_machine/state_test.rb +++ /dev/null @@ -1,72 +0,0 @@ -require 'test_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/state_machine/state_transition_test.rb b/activemodel/test/state_machine/state_transition_test.rb deleted file mode 100644 index b59ff5a6a7..0000000000 --- a/activemodel/test/state_machine/state_transition_test.rb +++ /dev/null @@ -1,84 +0,0 @@ -require 'test_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/state_machine_test.rb b/activemodel/test/state_machine_test.rb deleted file mode 100644 index 312d8728ba..0000000000 --- a/activemodel/test/state_machine_test.rb +++ /dev/null @@ -1,312 +0,0 @@ -require 'test_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/test_helper.rb b/activemodel/test/test_helper.rb deleted file mode 100644 index 5b5678e42d..0000000000 --- a/activemodel/test/test_helper.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'rubygems' -require 'test/unit' - -gem 'mocha', '>= 0.9.3' -require 'mocha' - -require 'active_model' -require 'active_model/state_machine' - -$:.unshift File.dirname(__FILE__) + "/../../activesupport/lib" -require 'active_support' -require 'active_support/test_case' - -class ActiveModel::TestCase < ActiveSupport::TestCase -end - -begin - require 'ruby-debug' - Debugger.start -rescue LoadError -end -- cgit v1.2.3 From e945bcfe4a519e6cf7349443c48fecce2e8c9d67 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 20 Mar 2009 11:22:27 +0000 Subject: Add test sqlite3 db to .gitignore --- activemodel/test/cases/helper.rb | 5 +---- activemodel/test/fixtures/fixture_database.sqlite3 | Bin 2048 -> 0 bytes 2 files changed, 1 insertion(+), 4 deletions(-) delete mode 100644 activemodel/test/fixtures/fixture_database.sqlite3 (limited to 'activemodel/test') diff --git a/activemodel/test/cases/helper.rb b/activemodel/test/cases/helper.rb index 6465f4e61f..1e5c6697cd 100644 --- a/activemodel/test/cases/helper.rb +++ b/activemodel/test/cases/helper.rb @@ -9,9 +9,6 @@ require 'active_record' require 'logger' ActiveRecord::Base.logger = Logger.new("debug.log") -class SqliteError < StandardError -end - # Setup database connection db_file = "#{FIXTURES_ROOT}/fixture_database.sqlite3" ActiveRecord::Base.configurations = { ActiveRecord::Base.name => { :adapter => 'sqlite3', :database => db_file, :timeout => 5000 } } @@ -19,7 +16,7 @@ unless File.exist?(db_file) puts "SQLite3 database not found at #{db_file}. Rebuilding it." sqlite_command = %Q{sqlite3 "#{db_file}" "create table a (a integer); drop table a;"} puts "Executing '#{sqlite_command}'" - raise SqliteError.new("Seems that there is no sqlite3 executable available") unless system(sqlite_command) + raise StandardError.new("Seems that there is no sqlite3 executable available") unless system(sqlite_command) end ActiveRecord::Base.establish_connection(ActiveRecord::Base.name) diff --git a/activemodel/test/fixtures/fixture_database.sqlite3 b/activemodel/test/fixtures/fixture_database.sqlite3 deleted file mode 100644 index 3847b16aca..0000000000 Binary files a/activemodel/test/fixtures/fixture_database.sqlite3 and /dev/null differ -- cgit v1.2.3 From 60756ad4ece2298e85353ed50853f1d260e0d27a Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 20 Mar 2009 15:07:49 +0000 Subject: Move relevant validation tests from Active Record to Active Model --- activemodel/test/cases/helper.rb | 17 +- activemodel/test/cases/test_database.rb | 31 + .../validations/acceptance_validation_test.rb | 73 +++ .../validations/conditional_validation_test.rb | 140 +++++ .../validations/confirmation_validation_test.rb | 51 ++ .../cases/validations/exclusion_validation_test.rb | 30 + .../cases/validations/format_validation_test.rb | 81 +++ .../i18n_generate_message_validation_test.rb | 174 ++++++ .../test/cases/validations/i18n_validation_test.rb | 672 +++++++++++++++++++++ .../cases/validations/inclusion_validation_test.rb | 63 ++ .../cases/validations/length_validation_test.rb | 443 ++++++++++++++ .../validations/numericality_validation_test.rb | 163 +++++ .../cases/validations/presence_validation_test.rb | 41 ++ activemodel/test/cases/validations_test.rb | 144 +++++ activemodel/test/models/developer.rb | 4 + activemodel/test/models/reply.rb | 30 + activemodel/test/models/topic.rb | 9 + 17 files changed, 2150 insertions(+), 16 deletions(-) create mode 100644 activemodel/test/cases/test_database.rb create mode 100644 activemodel/test/cases/validations/acceptance_validation_test.rb create mode 100644 activemodel/test/cases/validations/conditional_validation_test.rb create mode 100644 activemodel/test/cases/validations/confirmation_validation_test.rb create mode 100644 activemodel/test/cases/validations/exclusion_validation_test.rb create mode 100644 activemodel/test/cases/validations/format_validation_test.rb create mode 100644 activemodel/test/cases/validations/i18n_generate_message_validation_test.rb create mode 100644 activemodel/test/cases/validations/i18n_validation_test.rb create mode 100644 activemodel/test/cases/validations/inclusion_validation_test.rb create mode 100644 activemodel/test/cases/validations/length_validation_test.rb create mode 100644 activemodel/test/cases/validations/numericality_validation_test.rb create mode 100644 activemodel/test/cases/validations/presence_validation_test.rb create mode 100644 activemodel/test/cases/validations_test.rb create mode 100644 activemodel/test/models/developer.rb create mode 100644 activemodel/test/models/reply.rb create mode 100644 activemodel/test/models/topic.rb (limited to 'activemodel/test') diff --git a/activemodel/test/cases/helper.rb b/activemodel/test/cases/helper.rb index 1e5c6697cd..f023109a60 100644 --- a/activemodel/test/cases/helper.rb +++ b/activemodel/test/cases/helper.rb @@ -1,24 +1,9 @@ $:.unshift(File.dirname(__FILE__) + '/../../lib') -$:.unshift(File.dirname(__FILE__) + '/../../../activerecord/lib') $:.unshift(File.dirname(__FILE__) + '/../../../activesupport/lib') require 'config' -require 'active_model' - -require 'active_record' -require 'logger' -ActiveRecord::Base.logger = Logger.new("debug.log") -# Setup database connection -db_file = "#{FIXTURES_ROOT}/fixture_database.sqlite3" -ActiveRecord::Base.configurations = { ActiveRecord::Base.name => { :adapter => 'sqlite3', :database => db_file, :timeout => 5000 } } -unless File.exist?(db_file) - puts "SQLite3 database not found at #{db_file}. Rebuilding it." - sqlite_command = %Q{sqlite3 "#{db_file}" "create table a (a integer); drop table a;"} - puts "Executing '#{sqlite_command}'" - raise StandardError.new("Seems that there is no sqlite3 executable available") unless system(sqlite_command) -end -ActiveRecord::Base.establish_connection(ActiveRecord::Base.name) +require 'active_model' # Show backtraces for deprecated behavior for quicker cleanup. ActiveSupport::Deprecation.debug = true diff --git a/activemodel/test/cases/test_database.rb b/activemodel/test/cases/test_database.rb new file mode 100644 index 0000000000..509383ec59 --- /dev/null +++ b/activemodel/test/cases/test_database.rb @@ -0,0 +1,31 @@ +require 'logger' + +$:.unshift(File.dirname(__FILE__) + '/../../../activerecord/lib') +require 'active_record' +require 'active_record/fixtures' + +module ActiveModel + module TestDatabase + def self.included(base) + ActiveRecord::Base.logger = Logger.new("debug.log") + ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:') + + base.send :include, ActiveRecord::TestFixtures + base.setup :setup_database + end + + def setup_database + unless $schema_file_loaded + begin + # TODO : May the better way be with you + original, $stdout = $stdout, StringIO.new + load(SCHEMA_FILE) + ensure + $stdout = original + end + + $schema_file_loaded = true + end + end + end +end diff --git a/activemodel/test/cases/validations/acceptance_validation_test.rb b/activemodel/test/cases/validations/acceptance_validation_test.rb new file mode 100644 index 0000000000..f5f0279554 --- /dev/null +++ b/activemodel/test/cases/validations/acceptance_validation_test.rb @@ -0,0 +1,73 @@ +# encoding: utf-8 +require 'cases/helper' +require 'cases/test_database' + +require 'models/topic' +require 'models/reply' +require 'models/developer' + +class AcceptanceValidationTest < ActiveModel::TestCase + include ActiveModel::TestDatabase + include ActiveModel::ValidationsRepairHelper + + repair_validations(Topic) + + def test_terms_of_service_agreement_no_acceptance + Topic.validates_acceptance_of(:terms_of_service, :on => :create) + + t = Topic.create("title" => "We should not be confirmed") + assert t.save + end + + def test_terms_of_service_agreement + Topic.validates_acceptance_of(:terms_of_service, :on => :create) + + t = Topic.create("title" => "We should be confirmed","terms_of_service" => "") + assert !t.save + assert_equal ["must be accepted"], t.errors[:terms_of_service] + + t.terms_of_service = "1" + assert t.save + end + + def test_eula + Topic.validates_acceptance_of(:eula, :message => "must be abided", :on => :create) + + t = Topic.create("title" => "We should be confirmed","eula" => "") + assert !t.save + assert_equal ["must be abided"], t.errors[:eula] + + t.eula = "1" + assert t.save + end + + def test_terms_of_service_agreement_with_accept_value + Topic.validates_acceptance_of(:terms_of_service, :on => :create, :accept => "I agree.") + + t = Topic.create("title" => "We should be confirmed", "terms_of_service" => "") + assert !t.save + assert_equal ["must be accepted"], t.errors[:terms_of_service] + + t.terms_of_service = "I agree." + assert t.save + end + + def test_validates_acceptance_of_as_database_column + repair_validations(Reply) do + Reply.validates_acceptance_of(:author_name) + + reply = Reply.create("author_name" => "Dan Brown") + assert_equal "Dan Brown", reply["author_name"] + end + end + + def test_validates_acceptance_of_with_custom_error_using_quotes + repair_validations(Developer) do + Developer.validates_acceptance_of :salary, :message=> "This string contains 'single' and \"double\" quotes" + d = Developer.new + d.salary = "0" + assert !d.valid? + assert_equal "This string contains 'single' and \"double\" quotes", d.errors[:salary].last + end + end +end diff --git a/activemodel/test/cases/validations/conditional_validation_test.rb b/activemodel/test/cases/validations/conditional_validation_test.rb new file mode 100644 index 0000000000..d4cb3555f3 --- /dev/null +++ b/activemodel/test/cases/validations/conditional_validation_test.rb @@ -0,0 +1,140 @@ +# encoding: utf-8 +require 'cases/helper' +require 'cases/test_database' + +require 'models/topic' + +class ConditionalValidationTest < ActiveModel::TestCase + include ActiveModel::TestDatabase + include ActiveModel::ValidationsRepairHelper + + repair_validations(Topic) + + def test_if_validation_using_method_true + # When the method returns true + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => :condition_is_true ) + t = Topic.create("title" => "uhohuhoh", "content" => "whatever") + assert !t.valid? + assert t.errors[:title].any? + assert_equal ["hoo 5"], t.errors["title"] + end + + def test_unless_validation_using_method_true + # When the method returns true + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => :condition_is_true ) + t = Topic.create("title" => "uhohuhoh", "content" => "whatever") + assert t.valid? + assert !t.errors[:title].any? + end + + def test_if_validation_using_method_false + # When the method returns false + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => :condition_is_true_but_its_not ) + t = Topic.create("title" => "uhohuhoh", "content" => "whatever") + assert t.valid? + assert t.errors[:title].empty? + end + + def test_unless_validation_using_method_false + # When the method returns false + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => :condition_is_true_but_its_not ) + t = Topic.create("title" => "uhohuhoh", "content" => "whatever") + assert !t.valid? + assert t.errors[:title].any? + assert_equal ["hoo 5"], t.errors["title"] + end + + def test_if_validation_using_string_true + # When the evaluated string returns true + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => "a = 1; a == 1" ) + t = Topic.create("title" => "uhohuhoh", "content" => "whatever") + assert !t.valid? + assert t.errors[:title].any? + assert_equal ["hoo 5"], t.errors["title"] + end + + def test_unless_validation_using_string_true + # When the evaluated string returns true + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => "a = 1; a == 1" ) + t = Topic.create("title" => "uhohuhoh", "content" => "whatever") + assert t.valid? + assert t.errors[:title].empty? + end + + def test_if_validation_using_string_false + # When the evaluated string returns false + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => "false") + t = Topic.create("title" => "uhohuhoh", "content" => "whatever") + assert t.valid? + assert t.errors[:title].empty? + end + + def test_unless_validation_using_string_false + # When the evaluated string returns false + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => "false") + t = Topic.create("title" => "uhohuhoh", "content" => "whatever") + assert !t.valid? + assert t.errors[:title].any? + assert_equal ["hoo 5"], t.errors["title"] + end + + def test_if_validation_using_block_true + # When the block returns true + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", + :if => Proc.new { |r| r.content.size > 4 } ) + t = Topic.create("title" => "uhohuhoh", "content" => "whatever") + assert !t.valid? + assert t.errors[:title].any? + assert_equal ["hoo 5"], t.errors["title"] + end + + def test_unless_validation_using_block_true + # When the block returns true + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", + :unless => Proc.new { |r| r.content.size > 4 } ) + t = Topic.create("title" => "uhohuhoh", "content" => "whatever") + assert t.valid? + assert t.errors[:title].empty? + end + + def test_if_validation_using_block_false + # When the block returns false + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", + :if => Proc.new { |r| r.title != "uhohuhoh"} ) + t = Topic.create("title" => "uhohuhoh", "content" => "whatever") + assert t.valid? + assert t.errors[:title].empty? + end + + def test_unless_validation_using_block_false + # When the block returns false + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", + :unless => Proc.new { |r| r.title != "uhohuhoh"} ) + t = Topic.create("title" => "uhohuhoh", "content" => "whatever") + assert !t.valid? + assert t.errors[:title].any? + assert_equal ["hoo 5"], t.errors["title"] + end + + # previous implementation of validates_presence_of eval'd the + # string with the wrong binding, this regression test is to + # ensure that it works correctly + def test_validation_with_if_as_string + Topic.validates_presence_of(:title) + Topic.validates_presence_of(:author_name, :if => "title.to_s.match('important')") + + t = Topic.new + assert !t.valid?, "A topic without a title should not be valid" + assert !t.errors.invalid?("author_name"), "A topic without an 'important' title should not require an author" + + t.title = "Just a title" + assert t.valid?, "A topic with a basic title should be valid" + + t.title = "A very important title" + assert !t.valid?, "A topic with an important title, but without an author, should not be valid" + assert t.errors.invalid?("author_name"), "A topic with an 'important' title should require an author" + + t.author_name = "Hubert J. Farnsworth" + assert t.valid?, "A topic with an important title and author should be valid" + end +end diff --git a/activemodel/test/cases/validations/confirmation_validation_test.rb b/activemodel/test/cases/validations/confirmation_validation_test.rb new file mode 100644 index 0000000000..c3caa63d0b --- /dev/null +++ b/activemodel/test/cases/validations/confirmation_validation_test.rb @@ -0,0 +1,51 @@ +# encoding: utf-8 +require 'cases/helper' +require 'cases/test_database' + +require 'models/topic' +require 'models/developer' + +class ConfirmationValidationTest < ActiveModel::TestCase + include ActiveModel::TestDatabase + include ActiveModel::ValidationsRepairHelper + + repair_validations(Topic) + + def test_no_title_confirmation + Topic.validates_confirmation_of(:title) + + t = Topic.new(:author_name => "Plutarch") + assert t.valid? + + t.title_confirmation = "Parallel Lives" + assert !t.valid? + + t.title_confirmation = nil + t.title = "Parallel Lives" + assert t.valid? + + t.title_confirmation = "Parallel Lives" + assert t.valid? + end + + def test_title_confirmation + Topic.validates_confirmation_of(:title) + + t = Topic.create("title" => "We should be confirmed","title_confirmation" => "") + assert !t.save + + t.title_confirmation = "We should be confirmed" + assert t.save + end + + def test_validates_confirmation_of_with_custom_error_using_quotes + repair_validations(Developer) do + Developer.validates_confirmation_of :name, :message=> "confirm 'single' and \"double\" quotes" + d = Developer.new + d.name = "John" + d.name_confirmation = "Johnny" + assert !d.valid? + assert_equal ["confirm 'single' and \"double\" quotes"], d.errors[:name] + end + end +end diff --git a/activemodel/test/cases/validations/exclusion_validation_test.rb b/activemodel/test/cases/validations/exclusion_validation_test.rb new file mode 100644 index 0000000000..2e3da3c079 --- /dev/null +++ b/activemodel/test/cases/validations/exclusion_validation_test.rb @@ -0,0 +1,30 @@ +# encoding: utf-8 +require 'cases/helper' +require 'cases/test_database' + +require 'models/topic' + +class ExclusionValidationTest < ActiveModel::TestCase + include ActiveModel::TestDatabase + include ActiveModel::ValidationsRepairHelper + + repair_validations(Topic) + + def test_validates_exclusion_of + Topic.validates_exclusion_of( :title, :in => %w( abe monkey ) ) + + assert Topic.create("title" => "something", "content" => "abc").valid? + assert !Topic.create("title" => "monkey", "content" => "abc").valid? + end + + def test_validates_exclusion_of_with_formatted_message + Topic.validates_exclusion_of( :title, :in => %w( abe monkey ), :message => "option {{value}} is restricted" ) + + assert Topic.create("title" => "something", "content" => "abc") + + t = Topic.create("title" => "monkey") + assert !t.valid? + assert t.errors.on(:title) + assert_equal "option monkey is restricted", t.errors.on(:title) + end +end diff --git a/activemodel/test/cases/validations/format_validation_test.rb b/activemodel/test/cases/validations/format_validation_test.rb new file mode 100644 index 0000000000..9a7a93a6c6 --- /dev/null +++ b/activemodel/test/cases/validations/format_validation_test.rb @@ -0,0 +1,81 @@ +# encoding: utf-8 +require 'cases/helper' +require 'cases/test_database' + +require 'models/topic' + +class PresenceValidationTest < ActiveModel::TestCase + include ActiveModel::TestDatabase + include ActiveModel::ValidationsRepairHelper + + repair_validations(Topic) + + def test_validate_format + Topic.validates_format_of(:title, :content, :with => /^Validation\smacros \w+!$/, :message => "is bad data") + + t = Topic.create("title" => "i'm incorrect", "content" => "Validation macros rule!") + assert !t.valid?, "Shouldn't be valid" + assert !t.save, "Shouldn't save because it's invalid" + assert_equal ["is bad data"], t.errors[:title] + assert t.errors[:content].empty? + + t.title = "Validation macros rule!" + + assert t.save + assert t.errors[:title].empty? + + assert_raise(ArgumentError) { Topic.validates_format_of(:title, :content) } + end + + def test_validate_format_with_allow_blank + Topic.validates_format_of(:title, :with => /^Validation\smacros \w+!$/, :allow_blank=>true) + assert !Topic.create("title" => "Shouldn't be valid").valid? + assert Topic.create("title" => "").valid? + assert Topic.create("title" => nil).valid? + assert Topic.create("title" => "Validation macros rule!").valid? + end + + # testing ticket #3142 + def test_validate_format_numeric + Topic.validates_format_of(:title, :content, :with => /^[1-9][0-9]*$/, :message => "is bad data") + + t = Topic.create("title" => "72x", "content" => "6789") + assert !t.valid?, "Shouldn't be valid" + assert !t.save, "Shouldn't save because it's invalid" + assert_equal ["is bad data"], t.errors[:title] + assert t.errors[:content].empty? + + t.title = "-11" + assert !t.valid?, "Shouldn't be valid" + + t.title = "03" + assert !t.valid?, "Shouldn't be valid" + + t.title = "z44" + assert !t.valid?, "Shouldn't be valid" + + t.title = "5v7" + assert !t.valid?, "Shouldn't be valid" + + t.title = "1" + + assert t.save + assert t.errors[:title].empty? + end + + def test_validate_format_with_formatted_message + Topic.validates_format_of(:title, :with => /^Valid Title$/, :message => "can't be {{value}}") + t = Topic.create(:title => 'Invalid title') + assert_equal "can't be Invalid title", t.errors.on(:title) + end + + def test_validates_format_of_with_custom_error_using_quotes + repair_validations(Developer) do + Developer.validates_format_of :name, :with => /^(A-Z*)$/, :message=> "format 'single' and \"double\" quotes" + d = Developer.new + d.name = d.name_confirmation = "John 32" + assert !d.valid? + assert_equal ["format 'single' and \"double\" quotes"], d.errors[:name] + end + end +end diff --git a/activemodel/test/cases/validations/i18n_generate_message_validation_test.rb b/activemodel/test/cases/validations/i18n_generate_message_validation_test.rb new file mode 100644 index 0000000000..871c69d06d --- /dev/null +++ b/activemodel/test/cases/validations/i18n_generate_message_validation_test.rb @@ -0,0 +1,174 @@ +require "cases/helper" +require 'models/topic' +require 'models/reply' + +class I18nGenerateMessageValidationTest < Test::Unit::TestCase + def setup + reset_callbacks Topic + @topic = Topic.new + I18n.backend.store_translations :'en', { + :activerecord => { + :errors => { + :messages => { + :inclusion => "is not included in the list", + :exclusion => "is reserved", + :invalid => "is invalid", + :confirmation => "doesn't match confirmation", + :accepted => "must be accepted", + :empty => "can't be empty", + :blank => "can't be blank", + :too_long => "is too long (maximum is {{count}} characters)", + :too_short => "is too short (minimum is {{count}} characters)", + :wrong_length => "is the wrong length (should be {{count}} characters)", + :not_a_number => "is not a number", + :greater_than => "must be greater than {{count}}", + :greater_than_or_equal_to => "must be greater than or equal to {{count}}", + :equal_to => "must be equal to {{count}}", + :less_than => "must be less than {{count}}", + :less_than_or_equal_to => "must be less than or equal to {{count}}", + :odd => "must be odd", + :even => "must be even" + } + } + } + } + end + + def reset_callbacks(*models) + models.each do |model| + model.instance_variable_set("@validate_callbacks", ActiveSupport::Callbacks::CallbackChain.new) + model.instance_variable_set("@validate_on_create_callbacks", ActiveSupport::Callbacks::CallbackChain.new) + model.instance_variable_set("@validate_on_update_callbacks", ActiveSupport::Callbacks::CallbackChain.new) + end + end + + # validates_inclusion_of: generate_message(attr_name, :inclusion, :default => configuration[:message], :value => value) + def test_generate_message_inclusion_with_default_message + assert_equal 'is not included in the list', @topic.errors.generate_message(:title, :inclusion, :default => nil, :value => 'title') + end + + def test_generate_message_inclusion_with_custom_message + assert_equal 'custom message title', @topic.errors.generate_message(:title, :inclusion, :default => 'custom message {{value}}', :value => 'title') + end + + # validates_exclusion_of: generate_message(attr_name, :exclusion, :default => configuration[:message], :value => value) + def test_generate_message_exclusion_with_default_message + assert_equal 'is reserved', @topic.errors.generate_message(:title, :exclusion, :default => nil, :value => 'title') + end + + def test_generate_message_exclusion_with_custom_message + assert_equal 'custom message title', @topic.errors.generate_message(:title, :exclusion, :default => 'custom message {{value}}', :value => 'title') + end + + # validates_associated: generate_message(attr_name, :invalid, :default => configuration[:message], :value => value) + # validates_format_of: generate_message(attr_name, :invalid, :default => configuration[:message], :value => value) + def test_generate_message_invalid_with_default_message + assert_equal 'is invalid', @topic.errors.generate_message(:title, :invalid, :default => nil, :value => 'title') + end + + def test_generate_message_invalid_with_custom_message + assert_equal 'custom message title', @topic.errors.generate_message(:title, :invalid, :default => 'custom message {{value}}', :value => 'title') + end + + # validates_confirmation_of: generate_message(attr_name, :confirmation, :default => configuration[:message]) + def test_generate_message_confirmation_with_default_message + assert_equal "doesn't match confirmation", @topic.errors.generate_message(:title, :confirmation, :default => nil) + end + + def test_generate_message_confirmation_with_custom_message + assert_equal 'custom message', @topic.errors.generate_message(:title, :confirmation, :default => 'custom message') + end + + # validates_acceptance_of: generate_message(attr_name, :accepted, :default => configuration[:message]) + def test_generate_message_accepted_with_default_message + assert_equal "must be accepted", @topic.errors.generate_message(:title, :accepted, :default => nil) + end + + def test_generate_message_accepted_with_custom_message + assert_equal 'custom message', @topic.errors.generate_message(:title, :accepted, :default => 'custom message') + end + + # add_on_empty: generate_message(attr, :empty, :default => custom_message) + def test_generate_message_empty_with_default_message + assert_equal "can't be empty", @topic.errors.generate_message(:title, :empty, :default => nil) + end + + def test_generate_message_empty_with_custom_message + assert_equal 'custom message', @topic.errors.generate_message(:title, :empty, :default => 'custom message') + end + + # add_on_blank: generate_message(attr, :blank, :default => custom_message) + def test_generate_message_blank_with_default_message + assert_equal "can't be blank", @topic.errors.generate_message(:title, :blank, :default => nil) + end + + def test_generate_message_blank_with_custom_message + assert_equal 'custom message', @topic.errors.generate_message(:title, :blank, :default => 'custom message') + end + + # validates_length_of: generate_message(attr, :too_long, :default => options[:too_long], :count => option_value.end) + def test_generate_message_too_long_with_default_message + assert_equal "is too long (maximum is 10 characters)", @topic.errors.generate_message(:title, :too_long, :default => nil, :count => 10) + end + + def test_generate_message_too_long_with_custom_message + assert_equal 'custom message 10', @topic.errors.generate_message(:title, :too_long, :default => 'custom message {{count}}', :count => 10) + end + + # validates_length_of: generate_message(attr, :too_short, :default => options[:too_short], :count => option_value.begin) + def test_generate_message_too_short_with_default_message + assert_equal "is too short (minimum is 10 characters)", @topic.errors.generate_message(:title, :too_short, :default => nil, :count => 10) + end + + def test_generate_message_too_short_with_custom_message + assert_equal 'custom message 10', @topic.errors.generate_message(:title, :too_short, :default => 'custom message {{count}}', :count => 10) + end + + # validates_length_of: generate_message(attr, key, :default => custom_message, :count => option_value) + def test_generate_message_wrong_length_with_default_message + assert_equal "is the wrong length (should be 10 characters)", @topic.errors.generate_message(:title, :wrong_length, :default => nil, :count => 10) + end + + def test_generate_message_wrong_length_with_custom_message + assert_equal 'custom message 10', @topic.errors.generate_message(:title, :wrong_length, :default => 'custom message {{count}}', :count => 10) + end + + # validates_numericality_of: generate_message(attr_name, :not_a_number, :value => raw_value, :default => configuration[:message]) + def test_generate_message_not_a_number_with_default_message + assert_equal "is not a number", @topic.errors.generate_message(:title, :not_a_number, :default => nil, :value => 'title') + end + + def test_generate_message_not_a_number_with_custom_message + assert_equal 'custom message title', @topic.errors.generate_message(:title, :not_a_number, :default => 'custom message {{value}}', :value => 'title') + end + + # validates_numericality_of: generate_message(attr_name, option, :value => raw_value, :default => configuration[:message]) + def test_generate_message_greater_than_with_default_message + assert_equal "must be greater than 10", @topic.errors.generate_message(:title, :greater_than, :default => nil, :value => 'title', :count => 10) + end + + def test_generate_message_greater_than_or_equal_to_with_default_message + assert_equal "must be greater than or equal to 10", @topic.errors.generate_message(:title, :greater_than_or_equal_to, :default => nil, :value => 'title', :count => 10) + end + + def test_generate_message_equal_to_with_default_message + assert_equal "must be equal to 10", @topic.errors.generate_message(:title, :equal_to, :default => nil, :value => 'title', :count => 10) + end + + def test_generate_message_less_than_with_default_message + assert_equal "must be less than 10", @topic.errors.generate_message(:title, :less_than, :default => nil, :value => 'title', :count => 10) + end + + def test_generate_message_less_than_or_equal_to_with_default_message + assert_equal "must be less than or equal to 10", @topic.errors.generate_message(:title, :less_than_or_equal_to, :default => nil, :value => 'title', :count => 10) + end + + def test_generate_message_odd_with_default_message + assert_equal "must be odd", @topic.errors.generate_message(:title, :odd, :default => nil, :value => 'title', :count => 10) + end + + def test_generate_message_even_with_default_message + assert_equal "must be even", @topic.errors.generate_message(:title, :even, :default => nil, :value => 'title', :count => 10) + end + +end diff --git a/activemodel/test/cases/validations/i18n_validation_test.rb b/activemodel/test/cases/validations/i18n_validation_test.rb new file mode 100644 index 0000000000..2b2e52ca82 --- /dev/null +++ b/activemodel/test/cases/validations/i18n_validation_test.rb @@ -0,0 +1,672 @@ +require "cases/helper" +require 'models/topic' +require 'models/reply' + +class I18nValidationTest < ActiveModel::TestCase + include ActiveModel::TestDatabase + + def setup + reset_callbacks Topic + @topic = Topic.new + @old_load_path, @old_backend = I18n.load_path, I18n.backend + I18n.load_path.clear + I18n.backend = I18n::Backend::Simple.new + I18n.backend.store_translations('en', :activerecord => {:errors => {:messages => {:custom => nil}}}) + end + + def teardown + reset_callbacks Topic + I18n.load_path.replace @old_load_path + I18n.backend = @old_backend + end + + def reset_callbacks(*models) + models.each do |model| + model.instance_variable_set("@validate_callbacks", ActiveSupport::Callbacks::CallbackChain.new) + model.instance_variable_set("@validate_on_create_callbacks", ActiveSupport::Callbacks::CallbackChain.new) + model.instance_variable_set("@validate_on_update_callbacks", ActiveSupport::Callbacks::CallbackChain.new) + end + end + + def test_default_error_messages_is_deprecated + assert_deprecated('Errors.default_error_messages') do + ActiveModel::Errors.default_error_messages + end + end + + def test_percent_s_interpolation_syntax_in_error_messages_still_works + ActiveSupport::Deprecation.silence do + result = I18n.t :does_not_exist, :default => "%s interpolation syntax is deprecated", :value => 'this' + assert_equal result, "this interpolation syntax is deprecated" + end + end + + def test_percent_s_interpolation_syntax_in_error_messages_is_deprecated + assert_deprecated('using %s in messages') do + I18n.t :does_not_exist, :default => "%s interpolation syntax is deprected", :value => 'this' + end + end + + def test_percent_d_interpolation_syntax_in_error_messages_still_works + ActiveSupport::Deprecation.silence do + result = I18n.t :does_not_exist, :default => "%d interpolation syntaxes are deprecated", :count => 2 + assert_equal result, "2 interpolation syntaxes are deprecated" + end + end + + def test_percent_d_interpolation_syntax_in_error_messages_is_deprecated + assert_deprecated('using %d in messages') do + I18n.t :does_not_exist, :default => "%d interpolation syntaxes are deprected", :count => 2 + end + end + + # ActiveModel::Errors + def test_errors_generate_message_translates_custom_model_attribute_key + + I18n.expects(:translate).with( + :topic, + { :count => 1, + :default => ['Topic'], + :scope => [:activerecord, :models] + } + ).returns('Topic') + + I18n.expects(:translate).with( + :"topic.title", + { :count => 1, + :default => ['Title'], + :scope => [:activerecord, :attributes] + } + ).returns('Title') + + I18n.expects(:translate).with( + :"models.topic.attributes.title.invalid", + :value => nil, + :scope => [:activerecord, :errors], + :default => [ + :"models.topic.invalid", + 'default from class def error 1', + :"messages.invalid"], + :attribute => "Title", + :model => "Topic" + ).returns('default from class def error 1') + + @topic.errors.generate_message :title, :invalid, :default => 'default from class def error 1' + end + + def test_errors_generate_message_translates_custom_model_attribute_keys_with_sti + + I18n.expects(:translate).with( + :reply, + { :count => 1, + :default => [:topic, 'Reply'], + :scope => [:activerecord, :models] + } + ).returns('Reply') + + I18n.expects(:translate).with( + :"reply.title", + { :count => 1, + :default => [:'topic.title', 'Title'], + :scope => [:activerecord, :attributes] + } + ).returns('Title') + + I18n.expects(:translate).with( + :"models.reply.attributes.title.invalid", + :value => nil, + :scope => [:activerecord, :errors], + :default => [ + :"models.reply.invalid", + :"models.topic.attributes.title.invalid", + :"models.topic.invalid", + 'default from class def', + :"messages.invalid"], + :model => 'Reply', + :attribute => 'Title' + ).returns("default from class def") + + Reply.new.errors.generate_message :title, :invalid, :default => 'default from class def' + + end + + def test_errors_add_on_empty_generates_message + @topic.errors.expects(:generate_message).with(:title, :empty, {:default => nil}) + @topic.errors.add_on_empty :title + end + + def test_errors_add_on_empty_generates_message_with_custom_default_message + @topic.errors.expects(:generate_message).with(:title, :empty, {:default => 'custom'}) + @topic.errors.add_on_empty :title, 'custom' + end + + def test_errors_add_on_blank_generates_message + @topic.errors.expects(:generate_message).with(:title, :blank, {:default => nil}) + @topic.errors.add_on_blank :title + end + + def test_errors_add_on_blank_generates_message_with_custom_default_message + @topic.errors.expects(:generate_message).with(:title, :blank, {:default => 'custom'}) + @topic.errors.add_on_blank :title, 'custom' + end + + def test_errors_full_messages_translates_human_attribute_name_for_model_attributes + @topic.errors.add('title', 'empty') + I18n.expects(:translate).with(:"topic.title", :default => ['Title'], :scope => [:activerecord, :attributes], :count => 1).returns('Title') + @topic.errors.full_messages :locale => 'en' + end + + # ActiveRecord::Validations + # validates_confirmation_of w/ mocha + def test_validates_confirmation_of_generates_message + Topic.validates_confirmation_of :title + @topic.title_confirmation = 'foo' + @topic.errors.expects(:generate_message).with(:title, :confirmation, {:default => nil}) + @topic.valid? + end + + def test_validates_confirmation_of_generates_message_with_custom_default_message + Topic.validates_confirmation_of :title, :message => 'custom' + @topic.title_confirmation = 'foo' + @topic.errors.expects(:generate_message).with(:title, :confirmation, {:default => 'custom'}) + @topic.valid? + end + + # validates_acceptance_of w/ mocha + + def test_validates_acceptance_of_generates_message + Topic.validates_acceptance_of :title, :allow_nil => false + @topic.errors.expects(:generate_message).with(:title, :accepted, {:default => nil}) + @topic.valid? + end + + def test_validates_acceptance_of_generates_message_with_custom_default_message + Topic.validates_acceptance_of :title, :message => 'custom', :allow_nil => false + @topic.errors.expects(:generate_message).with(:title, :accepted, {:default => 'custom'}) + @topic.valid? + end + + # validates_presence_of w/ mocha + + def test_validates_presence_of_generates_message + Topic.validates_presence_of :title + @topic.errors.expects(:generate_message).with(:title, :blank, {:default => nil}) + @topic.valid? + end + + def test_validates_presence_of_generates_message_with_custom_default_message + Topic.validates_presence_of :title, :message => 'custom' + @topic.errors.expects(:generate_message).with(:title, :blank, {:default => 'custom'}) + @topic.valid? + end + + def test_validates_length_of_within_generates_message_with_title_too_short + Topic.validates_length_of :title, :within => 3..5 + @topic.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => nil}) + @topic.valid? + end + + def test_validates_length_of_within_generates_message_with_title_too_short_and_custom_default_message + Topic.validates_length_of :title, :within => 3..5, :too_short => 'custom' + @topic.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => 'custom'}) + @topic.valid? + end + + def test_validates_length_of_within_generates_message_with_title_too_long + Topic.validates_length_of :title, :within => 3..5 + @topic.title = 'this title is too long' + @topic.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => nil}) + @topic.valid? + end + + def test_validates_length_of_within_generates_message_with_title_too_long_and_custom_default_message + Topic.validates_length_of :title, :within => 3..5, :too_long => 'custom' + @topic.title = 'this title is too long' + @topic.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => 'custom'}) + @topic.valid? + end + + # validates_length_of :within w/ mocha + + def test_validates_length_of_within_generates_message_with_title_too_short + Topic.validates_length_of :title, :within => 3..5 + @topic.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => nil}) + @topic.valid? + end + + def test_validates_length_of_within_generates_message_with_title_too_short_and_custom_default_message + Topic.validates_length_of :title, :within => 3..5, :too_short => 'custom' + @topic.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => 'custom'}) + @topic.valid? + end + + def test_validates_length_of_within_generates_message_with_title_too_long + Topic.validates_length_of :title, :within => 3..5 + @topic.title = 'this title is too long' + @topic.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => nil}) + @topic.valid? + end + + def test_validates_length_of_within_generates_message_with_title_too_long_and_custom_default_message + Topic.validates_length_of :title, :within => 3..5, :too_long => 'custom' + @topic.title = 'this title is too long' + @topic.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => 'custom'}) + @topic.valid? + end + + # validates_length_of :is w/ mocha + + def test_validates_length_of_is_generates_message + Topic.validates_length_of :title, :is => 5 + @topic.errors.expects(:generate_message).with(:title, :wrong_length, {:count => 5, :default => nil}) + @topic.valid? + end + + def test_validates_length_of_is_generates_message_with_custom_default_message + Topic.validates_length_of :title, :is => 5, :message => 'custom' + @topic.errors.expects(:generate_message).with(:title, :wrong_length, {:count => 5, :default => 'custom'}) + @topic.valid? + end + + # validates_format_of w/ mocha + + def test_validates_format_of_generates_message + Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/ + @topic.title = '72x' + @topic.errors.expects(:generate_message).with(:title, :invalid, {:value => '72x', :default => nil}) + @topic.valid? + end + + def test_validates_format_of_generates_message_with_custom_default_message + Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/, :message => 'custom' + @topic.title = '72x' + @topic.errors.expects(:generate_message).with(:title, :invalid, {:value => '72x', :default => 'custom'}) + @topic.valid? + end + + # validates_inclusion_of w/ mocha + + def test_validates_inclusion_of_generates_message + Topic.validates_inclusion_of :title, :in => %w(a b c) + @topic.title = 'z' + @topic.errors.expects(:generate_message).with(:title, :inclusion, {:value => 'z', :default => nil}) + @topic.valid? + end + + def test_validates_inclusion_of_generates_message_with_custom_default_message + Topic.validates_inclusion_of :title, :in => %w(a b c), :message => 'custom' + @topic.title = 'z' + @topic.errors.expects(:generate_message).with(:title, :inclusion, {:value => 'z', :default => 'custom'}) + @topic.valid? + end + + # validates_exclusion_of w/ mocha + + def test_validates_exclusion_of_generates_message + Topic.validates_exclusion_of :title, :in => %w(a b c) + @topic.title = 'a' + @topic.errors.expects(:generate_message).with(:title, :exclusion, {:value => 'a', :default => nil}) + @topic.valid? + end + + def test_validates_exclusion_of_generates_message_with_custom_default_message + Topic.validates_exclusion_of :title, :in => %w(a b c), :message => 'custom' + @topic.title = 'a' + @topic.errors.expects(:generate_message).with(:title, :exclusion, {:value => 'a', :default => 'custom'}) + @topic.valid? + end + + # validates_numericality_of without :only_integer w/ mocha + + def test_validates_numericality_of_generates_message + Topic.validates_numericality_of :title + @topic.title = 'a' + @topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => nil}) + @topic.valid? + end + + def test_validates_numericality_of_generates_message_with_custom_default_message + Topic.validates_numericality_of :title, :message => 'custom' + @topic.title = 'a' + @topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => 'custom'}) + @topic.valid? + end + + # validates_numericality_of with :only_integer w/ mocha + + def test_validates_numericality_of_only_integer_generates_message + Topic.validates_numericality_of :title, :only_integer => true + @topic.title = 'a' + @topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => nil}) + @topic.valid? + end + + def test_validates_numericality_of_only_integer_generates_message_with_custom_default_message + Topic.validates_numericality_of :title, :only_integer => true, :message => 'custom' + @topic.title = 'a' + @topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => 'custom'}) + @topic.valid? + end + + # validates_numericality_of :odd w/ mocha + + def test_validates_numericality_of_odd_generates_message + Topic.validates_numericality_of :title, :only_integer => true, :odd => true + @topic.title = 0 + @topic.errors.expects(:generate_message).with(:title, :odd, {:value => 0, :default => nil}) + @topic.valid? + end + + def test_validates_numericality_of_odd_generates_message_with_custom_default_message + Topic.validates_numericality_of :title, :only_integer => true, :odd => true, :message => 'custom' + @topic.title = 0 + @topic.errors.expects(:generate_message).with(:title, :odd, {:value => 0, :default => 'custom'}) + @topic.valid? + end + + # validates_numericality_of :less_than w/ mocha + + def test_validates_numericality_of_less_than_generates_message + Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0 + @topic.title = 1 + @topic.errors.expects(:generate_message).with(:title, :less_than, {:value => 1, :count => 0, :default => nil}) + @topic.valid? + end + + def test_validates_numericality_of_odd_generates_message_with_custom_default_message + Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0, :message => 'custom' + @topic.title = 1 + @topic.errors.expects(:generate_message).with(:title, :less_than, {:value => 1, :count => 0, :default => 'custom'}) + @topic.valid? + end + + # validates_confirmation_of w/o mocha + + def test_validates_confirmation_of_finds_custom_model_key_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:confirmation => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:confirmation => 'global message'}}} + + Topic.validates_confirmation_of :title + @topic.title_confirmation = 'foo' + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_confirmation_of_finds_global_default_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:confirmation => 'global message'}}} + + Topic.validates_confirmation_of :title + @topic.title_confirmation = 'foo' + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_acceptance_of w/o mocha + + def test_validates_acceptance_of_finds_custom_model_key_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:accepted => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:accepted => 'global message'}}} + + Topic.validates_acceptance_of :title, :allow_nil => false + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_acceptance_of_finds_global_default_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:accepted => 'global message'}}} + + Topic.validates_acceptance_of :title, :allow_nil => false + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_presence_of w/o mocha + + def test_validates_presence_of_finds_custom_model_key_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:blank => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:blank => 'global message'}}} + + Topic.validates_presence_of :title + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_presence_of_finds_global_default_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:blank => 'global message'}}} + + Topic.validates_presence_of :title + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_length_of :within w/o mocha + + def test_validates_length_of_within_finds_custom_model_key_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:too_short => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:too_short => 'global message'}}} + + Topic.validates_length_of :title, :within => 3..5 + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_length_of_within_finds_global_default_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:too_short => 'global message'}}} + + Topic.validates_length_of :title, :within => 3..5 + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_length_of :is w/o mocha + + def test_validates_length_of_is_finds_custom_model_key_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}} + + Topic.validates_length_of :title, :is => 5 + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_length_of_is_finds_global_default_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}} + + Topic.validates_length_of :title, :is => 5 + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + def test_validates_length_of_is_finds_custom_model_key_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}} + + Topic.validates_length_of :title, :is => 5 + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_length_of_is_finds_global_default_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}} + + Topic.validates_length_of :title, :is => 5 + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + + # validates_format_of w/o mocha + + def test_validates_format_of_finds_custom_model_key_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:invalid => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}} + + Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/ + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_format_of_finds_global_default_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}} + + Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/ + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_inclusion_of w/o mocha + + def test_validates_inclusion_of_finds_custom_model_key_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:inclusion => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:inclusion => 'global message'}}} + + Topic.validates_inclusion_of :title, :in => %w(a b c) + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_inclusion_of_finds_global_default_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:inclusion => 'global message'}}} + + Topic.validates_inclusion_of :title, :in => %w(a b c) + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_exclusion_of w/o mocha + + def test_validates_exclusion_of_finds_custom_model_key_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:exclusion => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:exclusion => 'global message'}}} + + Topic.validates_exclusion_of :title, :in => %w(a b c) + @topic.title = 'a' + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_exclusion_of_finds_global_default_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:exclusion => 'global message'}}} + + Topic.validates_exclusion_of :title, :in => %w(a b c) + @topic.title = 'a' + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_numericality_of without :only_integer w/o mocha + + def test_validates_numericality_of_finds_custom_model_key_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}} + + Topic.validates_numericality_of :title + @topic.title = 'a' + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_numericality_of_finds_global_default_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}} + + Topic.validates_numericality_of :title, :only_integer => true + @topic.title = 'a' + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # 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', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}} + + Topic.validates_numericality_of :title, :only_integer => true + @topic.title = 'a' + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_numericality_of_only_integer_finds_global_default_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}} + + Topic.validates_numericality_of :title, :only_integer => true + @topic.title = 'a' + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # validates_numericality_of :odd w/o mocha + + def test_validates_numericality_of_odd_finds_custom_model_key_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:odd => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:odd => 'global message'}}} + + Topic.validates_numericality_of :title, :only_integer => true, :odd => true + @topic.title = 0 + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_numericality_of_odd_finds_global_default_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:odd => 'global message'}}} + + Topic.validates_numericality_of :title, :only_integer => true, :odd => true + @topic.title = 0 + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + # 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', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:less_than => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:less_than => 'global message'}}} + + Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0 + @topic.title = 1 + @topic.valid? + assert_equal 'custom message', @topic.errors.on(:title) + end + + def test_validates_numericality_of_less_than_finds_global_default_translation + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:less_than => 'global message'}}} + + Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0 + @topic.title = 1 + @topic.valid? + assert_equal 'global message', @topic.errors.on(:title) + end + + def test_validations_with_message_symbol_must_translate + I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:custom_error => "I am a custom error"}}} + Topic.validates_presence_of :title, :message => :custom_error + @topic.title = nil + @topic.valid? + assert_equal "I am a custom error", @topic.errors.on(:title) + end + + def test_validates_with_message_symbol_must_translate_per_attribute + I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:custom_error => "I am a custom error"}}}}}} + Topic.validates_presence_of :title, :message => :custom_error + @topic.title = nil + @topic.valid? + assert_equal "I am a custom error", @topic.errors.on(:title) + end + + def test_validates_with_message_symbol_must_translate_per_model + I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:custom_error => "I am a custom error"}}}} + Topic.validates_presence_of :title, :message => :custom_error + @topic.title = nil + @topic.valid? + assert_equal "I am a custom error", @topic.errors.on(:title) + end + + def test_validates_with_message_string + Topic.validates_presence_of :title, :message => "I am a custom error" + @topic.title = nil + @topic.valid? + assert_equal "I am a custom error", @topic.errors.on(:title) + end + +end \ No newline at end of file diff --git a/activemodel/test/cases/validations/inclusion_validation_test.rb b/activemodel/test/cases/validations/inclusion_validation_test.rb new file mode 100644 index 0000000000..7b2020c719 --- /dev/null +++ b/activemodel/test/cases/validations/inclusion_validation_test.rb @@ -0,0 +1,63 @@ +# encoding: utf-8 +require 'cases/helper' +require 'cases/test_database' + +require 'models/topic' + +class InclusionValidationTest < ActiveModel::TestCase + include ActiveModel::TestDatabase + include ActiveModel::ValidationsRepairHelper + + repair_validations(Topic) + + def test_validates_inclusion_of + Topic.validates_inclusion_of( :title, :in => %w( a b c d e f g ) ) + + assert !Topic.create("title" => "a!", "content" => "abc").valid? + assert !Topic.create("title" => "a b", "content" => "abc").valid? + assert !Topic.create("title" => nil, "content" => "def").valid? + + t = Topic.create("title" => "a", "content" => "I know you are but what am I?") + assert t.valid? + t.title = "uhoh" + assert !t.valid? + assert t.errors.on(:title) + assert_equal "is not included in the list", t.errors.on(:title) + + assert_raise(ArgumentError) { Topic.validates_inclusion_of( :title, :in => nil ) } + assert_raise(ArgumentError) { Topic.validates_inclusion_of( :title, :in => 0) } + + assert_nothing_raised(ArgumentError) { Topic.validates_inclusion_of( :title, :in => "hi!" ) } + assert_nothing_raised(ArgumentError) { Topic.validates_inclusion_of( :title, :in => {} ) } + assert_nothing_raised(ArgumentError) { Topic.validates_inclusion_of( :title, :in => [] ) } + end + + def test_validates_inclusion_of_with_allow_nil + Topic.validates_inclusion_of( :title, :in => %w( a b c d e f g ), :allow_nil=>true ) + + assert !Topic.create("title" => "a!", "content" => "abc").valid? + assert !Topic.create("title" => "", "content" => "abc").valid? + assert Topic.create("title" => nil, "content" => "abc").valid? + end + + def test_validates_inclusion_of_with_formatted_message + Topic.validates_inclusion_of( :title, :in => %w( a b c d e f g ), :message => "option {{value}} is not in the list" ) + + assert Topic.create("title" => "a", "content" => "abc").valid? + + t = Topic.create("title" => "uhoh", "content" => "abc") + assert !t.valid? + assert t.errors.on(:title) + assert_equal "option uhoh is not in the list", t.errors.on(:title) + end + + def test_validates_inclusion_of_with_custom_error_using_quotes + repair_validations(Developer) do + Developer.validates_inclusion_of :salary, :in => 1000..80000, :message=> "This string contains 'single' and \"double\" quotes" + d = Developer.new + d.salary = "90,000" + assert !d.valid? + assert_equal "This string contains 'single' and \"double\" quotes", d.errors[:salary].last + end + end +end diff --git a/activemodel/test/cases/validations/length_validation_test.rb b/activemodel/test/cases/validations/length_validation_test.rb new file mode 100644 index 0000000000..daca363b57 --- /dev/null +++ b/activemodel/test/cases/validations/length_validation_test.rb @@ -0,0 +1,443 @@ +# encoding: utf-8 +require 'cases/helper' +require 'cases/test_database' + +require 'models/topic' + +class LengthValidationTest < ActiveModel::TestCase + include ActiveModel::TestDatabase + include ActiveModel::ValidationsRepairHelper + + repair_validations(Topic) + + def test_validates_length_of_with_allow_nil + Topic.validates_length_of( :title, :is => 5, :allow_nil=>true ) + + assert !Topic.create("title" => "ab").valid? + assert !Topic.create("title" => "").valid? + assert Topic.create("title" => nil).valid? + assert Topic.create("title" => "abcde").valid? + end + + def test_validates_length_of_with_allow_blank + Topic.validates_length_of( :title, :is => 5, :allow_blank=>true ) + + assert !Topic.create("title" => "ab").valid? + assert Topic.create("title" => "").valid? + assert Topic.create("title" => nil).valid? + assert Topic.create("title" => "abcde").valid? + end + + def test_validates_length_of_using_minimum + Topic.validates_length_of :title, :minimum => 5 + + t = Topic.create("title" => "valid", "content" => "whatever") + assert t.valid? + + t.title = "not" + assert !t.valid? + assert t.errors.on(:title) + assert_equal "is too short (minimum is 5 characters)", t.errors.on(:title) + + t.title = "" + assert !t.valid? + assert t.errors.on(:title) + assert_equal "is too short (minimum is 5 characters)", t.errors.on(:title) + + t.title = nil + assert !t.valid? + assert t.errors.on(:title) + assert_equal ["is too short (minimum is 5 characters)"], t.errors["title"] + end + + def test_optionally_validates_length_of_using_minimum + Topic.validates_length_of :title, :minimum => 5, :allow_nil => true + + t = Topic.create("title" => "valid", "content" => "whatever") + assert t.valid? + + t.title = nil + assert t.valid? + end + + def test_validates_length_of_using_maximum + Topic.validates_length_of :title, :maximum => 5 + + t = Topic.create("title" => "valid", "content" => "whatever") + assert t.valid? + + t.title = "notvalid" + assert !t.valid? + assert t.errors.on(:title) + assert_equal "is too long (maximum is 5 characters)", t.errors.on(:title) + + t.title = "" + assert t.valid? + + t.title = nil + assert !t.valid? + end + + def test_optionally_validates_length_of_using_maximum + Topic.validates_length_of :title, :maximum => 5, :allow_nil => true + + t = Topic.create("title" => "valid", "content" => "whatever") + assert t.valid? + + t.title = nil + assert t.valid? + end + + def test_validates_length_of_using_within + Topic.validates_length_of(:title, :content, :within => 3..5) + + t = Topic.new("title" => "a!", "content" => "I'm ooooooooh so very long") + assert !t.valid? + assert_equal "is too short (minimum is 3 characters)", t.errors.on(:title) + assert_equal "is too long (maximum is 5 characters)", t.errors.on(:content) + + t.title = nil + t.content = nil + assert !t.valid? + assert_equal "is too short (minimum is 3 characters)", t.errors.on(:title) + assert_equal "is too short (minimum is 3 characters)", t.errors.on(:content) + + t.title = "abe" + t.content = "mad" + assert t.valid? + end + + def test_optionally_validates_length_of_using_within + Topic.validates_length_of :title, :content, :within => 3..5, :allow_nil => true + + t = Topic.create('title' => 'abc', 'content' => 'abcd') + assert t.valid? + + t.title = nil + assert t.valid? + end + + def test_optionally_validates_length_of_using_within_on_create + Topic.validates_length_of :title, :content, :within => 5..10, :on => :create, :too_long => "my string is too long: {{count}}" + + t = Topic.create("title" => "thisisnotvalid", "content" => "whatever") + assert !t.save + assert t.errors.on(:title) + assert_equal "my string is too long: 10", t.errors.on(:title) + + t.title = "butthisis" + assert t.save + + t.title = "few" + assert t.save + + t.content = "andthisislong" + assert t.save + + t.content = t.title = "iamfine" + assert t.save + end + + def test_optionally_validates_length_of_using_within_on_update + Topic.validates_length_of :title, :content, :within => 5..10, :on => :update, :too_short => "my string is too short: {{count}}" + + t = Topic.create("title" => "vali", "content" => "whatever") + assert !t.save + assert t.errors.on(:title) + + t.title = "not" + assert !t.save + assert t.errors.on(:title) + assert_equal "my string is too short: 5", t.errors.on(:title) + + t.title = "valid" + t.content = "andthisistoolong" + assert !t.save + assert t.errors.on(:content) + + t.content = "iamfine" + assert t.save + end + + def test_validates_length_of_using_is + Topic.validates_length_of :title, :is => 5 + + t = Topic.create("title" => "valid", "content" => "whatever") + assert t.valid? + + t.title = "notvalid" + assert !t.valid? + assert t.errors.on(:title) + assert_equal "is the wrong length (should be 5 characters)", t.errors.on(:title) + + t.title = "" + assert !t.valid? + + t.title = nil + assert !t.valid? + end + + def test_optionally_validates_length_of_using_is + Topic.validates_length_of :title, :is => 5, :allow_nil => true + + t = Topic.create("title" => "valid", "content" => "whatever") + assert t.valid? + + t.title = nil + assert t.valid? + end + + def test_validates_length_of_using_bignum + bigmin = 2 ** 30 + bigmax = 2 ** 32 + bigrange = bigmin...bigmax + assert_nothing_raised do + Topic.validates_length_of :title, :is => bigmin + 5 + Topic.validates_length_of :title, :within => bigrange + Topic.validates_length_of :title, :in => bigrange + Topic.validates_length_of :title, :minimum => bigmin + Topic.validates_length_of :title, :maximum => bigmax + end + end + + def test_validates_length_with_globally_modified_error_message + ActiveSupport::Deprecation.silence do + ActiveModel::Errors.default_error_messages[:too_short] = 'tu est trops petit hombre {{count}}' + end + Topic.validates_length_of :title, :minimum => 10 + t = Topic.create(:title => 'too short') + assert !t.valid? + + assert_equal 'tu est trops petit hombre 10', t.errors.on(:title) + end + + def test_validates_length_of_nasty_params + assert_raise(ArgumentError) { Topic.validates_length_of(:title, :minimum=>6, :maximum=>9) } + assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within=>6, :maximum=>9) } + assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within=>6, :minimum=>9) } + assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within=>6, :is=>9) } + assert_raise(ArgumentError) { Topic.validates_length_of(:title, :minimum=>"a") } + assert_raise(ArgumentError) { Topic.validates_length_of(:title, :maximum=>"a") } + assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within=>"a") } + assert_raise(ArgumentError) { Topic.validates_length_of(:title, :is=>"a") } + end + + def test_validates_length_of_custom_errors_for_minimum_with_message + Topic.validates_length_of( :title, :minimum=>5, :message=>"boo {{count}}" ) + t = Topic.create("title" => "uhoh", "content" => "whatever") + assert !t.valid? + assert t.errors.on(:title) + assert_equal "boo 5", t.errors.on(:title) + end + + def test_validates_length_of_custom_errors_for_minimum_with_too_short + Topic.validates_length_of( :title, :minimum=>5, :too_short=>"hoo {{count}}" ) + t = Topic.create("title" => "uhoh", "content" => "whatever") + assert !t.valid? + assert t.errors.on(:title) + assert_equal "hoo 5", t.errors.on(:title) + end + + def test_validates_length_of_custom_errors_for_maximum_with_message + Topic.validates_length_of( :title, :maximum=>5, :message=>"boo {{count}}" ) + t = Topic.create("title" => "uhohuhoh", "content" => "whatever") + assert !t.valid? + assert t.errors.on(:title) + assert_equal ["boo 5"], t.errors[:title] + end + + def test_validates_length_of_custom_errors_for_in + Topic.validates_length_of(:title, :in => 10..20, :message => "hoo {{count}}") + t = Topic.create("title" => "uhohuhoh", "content" => "whatever") + assert !t.valid? + assert t.errors[:title].any? + assert_equal ["hoo 10"], t.errors["title"] + + t = Topic.create("title" => "uhohuhohuhohuhohuhohuhohuhohuhoh", "content" => "whatever") + assert !t.valid? + assert t.errors[:title].any? + assert_equal ["hoo 20"], t.errors["title"] + end + + def test_validates_length_of_custom_errors_for_maximum_with_too_long + Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}" ) + t = Topic.create("title" => "uhohuhoh", "content" => "whatever") + assert !t.valid? + assert t.errors[:title].any? + assert_equal ["hoo 5"], t.errors["title"] + end + + def test_validates_length_of_custom_errors_for_is_with_message + Topic.validates_length_of( :title, :is=>5, :message=>"boo {{count}}" ) + t = Topic.create("title" => "uhohuhoh", "content" => "whatever") + assert !t.valid? + assert t.errors[:title].any? + assert_equal ["boo 5"], t.errors["title"] + end + + def test_validates_length_of_custom_errors_for_is_with_wrong_length + Topic.validates_length_of( :title, :is=>5, :wrong_length=>"hoo {{count}}" ) + t = Topic.create("title" => "uhohuhoh", "content" => "whatever") + assert !t.valid? + assert t.errors[:title].any? + assert_equal ["hoo 5"], t.errors["title"] + end + + def test_validates_length_of_using_minimum_utf8 + with_kcode('UTF8') do + Topic.validates_length_of :title, :minimum => 5 + + t = Topic.create("title" => "一二三四五", "content" => "whatever") + assert t.valid? + + t.title = "一二三四" + assert !t.valid? + assert t.errors[:title].any? + assert_equal ["is too short (minimum is 5 characters)"], t.errors["title"] + end + end + + def test_validates_length_of_using_maximum_utf8 + with_kcode('UTF8') do + Topic.validates_length_of :title, :maximum => 5 + + t = Topic.create("title" => "一二三四五", "content" => "whatever") + assert t.valid? + + t.title = "一二34五六" + assert !t.valid? + assert t.errors[:title].any? + assert_equal ["is too long (maximum is 5 characters)"], t.errors["title"] + end + end + + def test_validates_length_of_using_within_utf8 + with_kcode('UTF8') do + Topic.validates_length_of(:title, :content, :within => 3..5) + + t = Topic.new("title" => "一二", "content" => "12三四五六七") + assert !t.valid? + assert_equal ["is too short (minimum is 3 characters)"], t.errors[:title] + assert_equal ["is too long (maximum is 5 characters)"], t.errors[:content] + t.title = "一二三" + t.content = "12三" + assert t.valid? + end + end + + def test_optionally_validates_length_of_using_within_utf8 + with_kcode('UTF8') do + Topic.validates_length_of :title, :within => 3..5, :allow_nil => true + + t = Topic.create(:title => "一二三四五") + assert t.valid?, t.errors.inspect + + t = Topic.create(:title => "一二三") + assert t.valid?, t.errors.inspect + + t.title = nil + assert t.valid?, t.errors.inspect + end + end + + def test_optionally_validates_length_of_using_within_on_create_utf8 + with_kcode('UTF8') do + Topic.validates_length_of :title, :within => 5..10, :on => :create, :too_long => "長すぎます: {{count}}" + + t = Topic.create("title" => "一二三四五六七八九十A", "content" => "whatever") + assert !t.save + assert t.errors[:title].any? + assert_equal "長すぎます: 10", t.errors[:title].first + + t.title = "一二三四五六七八九" + assert t.save + + t.title = "一二3" + assert t.save + + t.content = "一二三四五六七八九十" + assert t.save + + t.content = t.title = "一二三四五六" + assert t.save + end + end + + def test_optionally_validates_length_of_using_within_on_update_utf8 + with_kcode('UTF8') do + Topic.validates_length_of :title, :within => 5..10, :on => :update, :too_short => "短すぎます: {{count}}" + + t = Topic.create("title" => "一二三4", "content" => "whatever") + assert !t.save + assert t.errors[:title].any? + + t.title = "1二三4" + assert !t.save + assert t.errors[:title].any? + assert_equal "短すぎます: 5", t.errors.on(:title) + + t.title = "一二三四五六七八九十A" + assert !t.save + assert t.errors[:title].any? + + t.title = "一二345" + assert t.save + end + end + + def test_validates_length_of_using_is_utf8 + with_kcode('UTF8') do + Topic.validates_length_of :title, :is => 5 + + t = Topic.create("title" => "一二345", "content" => "whatever") + assert t.valid? + + t.title = "一二345六" + assert !t.valid? + assert t.errors[:title].any? + assert_equal ["is the wrong length (should be 5 characters)"], t.errors["title"] + end + end + + def test_validates_length_of_with_block + Topic.validates_length_of :content, :minimum => 5, :too_short=>"Your essay must be at least {{count}} words.", + :tokenizer => lambda {|str| str.scan(/\w+/) } + t = Topic.create!(:content => "this content should be long enough") + assert t.valid? + + t.content = "not long enough" + assert !t.valid? + assert t.errors[:content].any? + assert_equal ["Your essay must be at least 5 words."], t.errors[:content] + end + + def test_validates_length_of_with_custom_too_long_using_quotes + repair_validations(Developer) do + Developer.validates_length_of :name, :maximum => 4, :too_long=> "This string contains 'single' and \"double\" quotes" + d = Developer.new + d.name = "Jeffrey" + assert !d.valid? + assert_equal ["This string contains 'single' and \"double\" quotes"], d.errors[:name] + end + end + + def test_validates_length_of_with_custom_too_short_using_quotes + repair_validations(Developer) do + Developer.validates_length_of :name, :minimum => 4, :too_short=> "This string contains 'single' and \"double\" quotes" + d = Developer.new + d.name = "Joe" + assert !d.valid? + assert_equal ["This string contains 'single' and \"double\" quotes"], d.errors[:name] + end + end + + def test_validates_length_of_with_custom_message_using_quotes + repair_validations(Developer) do + Developer.validates_length_of :name, :minimum => 4, :message=> "This string contains 'single' and \"double\" quotes" + d = Developer.new + d.name = "Joe" + assert !d.valid? + assert_equal ["This string contains 'single' and \"double\" quotes"], d.errors[:name] + end + end +end diff --git a/activemodel/test/cases/validations/numericality_validation_test.rb b/activemodel/test/cases/validations/numericality_validation_test.rb new file mode 100644 index 0000000000..3a30c0cec1 --- /dev/null +++ b/activemodel/test/cases/validations/numericality_validation_test.rb @@ -0,0 +1,163 @@ +# encoding: utf-8 +require 'cases/helper' +require 'cases/test_database' + +require 'models/topic' +require 'models/developer' + +class NumericalityValidationTest < ActiveModel::TestCase + include ActiveModel::TestDatabase + include ActiveModel::ValidationsRepairHelper + + repair_validations(Topic) + + NIL = [nil] + BLANK = ["", " ", " \t \r \n"] + BIGDECIMAL_STRINGS = %w(12345678901234567890.1234567890) # 30 significent digits + FLOAT_STRINGS = %w(0.0 +0.0 -0.0 10.0 10.5 -10.5 -0.0001 -090.1 90.1e1 -90.1e5 -90.1e-5 90e-5) + INTEGER_STRINGS = %w(0 +0 -0 10 +10 -10 0090 -090) + FLOATS = [0.0, 10.0, 10.5, -10.5, -0.0001] + FLOAT_STRINGS + INTEGERS = [0, 10, -10] + INTEGER_STRINGS + BIGDECIMAL = BIGDECIMAL_STRINGS.collect! { |bd| BigDecimal.new(bd) } + JUNK = ["not a number", "42 not a number", "0xdeadbeef", "00-1", "--3", "+-3", "+3-1", "-+019.0", "12.12.13.12", "123\nnot a number"] + INFINITY = [1.0/0.0] + + def test_default_validates_numericality_of + Topic.validates_numericality_of :approved + invalid!(NIL + BLANK + JUNK) + valid!(FLOATS + INTEGERS + BIGDECIMAL + INFINITY) + end + + def test_validates_numericality_of_with_nil_allowed + Topic.validates_numericality_of :approved, :allow_nil => true + + invalid!(JUNK) + valid!(NIL + BLANK + FLOATS + INTEGERS + BIGDECIMAL + INFINITY) + end + + def test_validates_numericality_of_with_integer_only + Topic.validates_numericality_of :approved, :only_integer => true + + invalid!(NIL + BLANK + JUNK + FLOATS + BIGDECIMAL + INFINITY) + valid!(INTEGERS) + end + + def test_validates_numericality_of_with_integer_only_and_nil_allowed + Topic.validates_numericality_of :approved, :only_integer => true, :allow_nil => true + + invalid!(JUNK + FLOATS + BIGDECIMAL + INFINITY) + valid!(NIL + BLANK + INTEGERS) + end + + def test_validates_numericality_with_greater_than + Topic.validates_numericality_of :approved, :greater_than => 10 + + invalid!([-10, 10], 'must be greater than 10') + valid!([11]) + end + + def test_validates_numericality_with_greater_than_or_equal + Topic.validates_numericality_of :approved, :greater_than_or_equal_to => 10 + + invalid!([-9, 9], 'must be greater than or equal to 10') + valid!([10]) + end + + def test_validates_numericality_with_equal_to + Topic.validates_numericality_of :approved, :equal_to => 10 + + invalid!([-10, 11] + INFINITY, 'must be equal to 10') + valid!([10]) + end + + def test_validates_numericality_with_less_than + Topic.validates_numericality_of :approved, :less_than => 10 + + invalid!([10], 'must be less than 10') + valid!([-9, 9]) + end + + def test_validates_numericality_with_less_than_or_equal_to + Topic.validates_numericality_of :approved, :less_than_or_equal_to => 10 + + invalid!([11], 'must be less than or equal to 10') + valid!([-10, 10]) + end + + def test_validates_numericality_with_odd + Topic.validates_numericality_of :approved, :odd => true + + invalid!([-2, 2], 'must be odd') + valid!([-1, 1]) + end + + def test_validates_numericality_with_even + Topic.validates_numericality_of :approved, :even => true + + invalid!([-1, 1], 'must be even') + valid!([-2, 2]) + end + + def test_validates_numericality_with_greater_than_less_than_and_even + Topic.validates_numericality_of :approved, :greater_than => 1, :less_than => 4, :even => true + + invalid!([1, 3, 4]) + valid!([2]) + end + + def test_validates_numericality_with_numeric_message + Topic.validates_numericality_of :approved, :less_than => 4, :message => "smaller than {{count}}" + topic = Topic.new("title" => "numeric test", "approved" => 10) + + assert !topic.valid? + assert_equal "smaller than 4", topic.errors.on(:approved) + + Topic.validates_numericality_of :approved, :greater_than => 4, :message => "greater than {{count}}" + topic = Topic.new("title" => "numeric test", "approved" => 1) + + assert !topic.valid? + assert_equal "greater than 4", topic.errors.on(:approved) + end + + private + + def invalid!(values, error = nil) + with_each_topic_approved_value(values) do |topic, value| + assert !topic.valid?, "#{value.inspect} not rejected as a number" + assert topic.errors[:approved].any?, "FAILED for #{value.inspect}" + assert_equal error, topic.errors[:approved].first if error + end + end + + def valid!(values) + with_each_topic_approved_value(values) do |topic, value| + assert topic.valid?, "#{value.inspect} not accepted as a number" + end + end + + def with_each_topic_approved_value(values) + topic = Topic.new(:title => "numeric test", :content => "whatever") + values.each do |value| + topic.approved = value + yield topic, value + end + end + + def test_numericality_with_getter_method + repair_validations(Developer) do + Developer.validates_numericality_of( :salary ) + developer = Developer.new("name" => "michael", "salary" => nil) + developer.instance_eval("def salary; read_attribute('salary') ? read_attribute('salary') : 100000; end") + assert developer.valid? + end + end + + def test_numericality_with_allow_nil_and_getter_method + repair_validations(Developer) do + Developer.validates_numericality_of( :salary, :allow_nil => true) + developer = Developer.new("name" => "michael", "salary" => nil) + developer.instance_eval("def salary; read_attribute('salary') ? read_attribute('salary') : 100000; end") + assert developer.valid? + end + end +end diff --git a/activemodel/test/cases/validations/presence_validation_test.rb b/activemodel/test/cases/validations/presence_validation_test.rb new file mode 100644 index 0000000000..5bf29be491 --- /dev/null +++ b/activemodel/test/cases/validations/presence_validation_test.rb @@ -0,0 +1,41 @@ +# encoding: utf-8 +require 'cases/helper' +require 'cases/test_database' + +require 'models/topic' + +class PresenceValidationTest < ActiveModel::TestCase + include ActiveModel::TestDatabase + include ActiveModel::ValidationsRepairHelper + + repair_validations(Topic) + + def test_validate_presences + Topic.validates_presence_of(:title, :content) + + t = Topic.create + assert !t.save + assert_equal ["can't be blank"], t.errors[:title] + assert_equal ["can't be blank"], t.errors[:content] + + t.title = "something" + t.content = " " + + assert !t.save + assert_equal ["can't be blank"], t.errors[:content] + + t.content = "like stuff" + + assert t.save + end + + def test_validates_presence_of_with_custom_message_using_quotes + repair_validations(Developer) do + Developer.validates_presence_of :non_existent, :message=> "This string contains 'single' and \"double\" quotes" + d = Developer.new + d.name = "Joe" + assert !d.valid? + assert_equal ["This string contains 'single' and \"double\" quotes"], d.errors[:non_existent] + end + end +end diff --git a/activemodel/test/cases/validations_test.rb b/activemodel/test/cases/validations_test.rb new file mode 100644 index 0000000000..a7269522eb --- /dev/null +++ b/activemodel/test/cases/validations_test.rb @@ -0,0 +1,144 @@ +# encoding: utf-8 +require 'cases/helper' +require 'cases/test_database' + +require 'models/topic' +require 'models/reply' +require 'models/developer' + +class ValidationsTest < ActiveModel::TestCase + include ActiveModel::TestDatabase + include ActiveModel::ValidationsRepairHelper + + fixtures :topics, :developers + + # Most of the tests mess with the validations of Topic, so lets repair it all the time. + # Other classes we mess with will be dealt with in the specific tests + repair_validations(Topic) + + def test_single_field_validation + r = Reply.new + r.title = "There's no content!" + assert !r.valid?, "A reply without content shouldn't be saveable" + + r.content = "Messa content!" + assert r.valid?, "A reply with content should be saveable" + end + + def test_single_attr_validation_and_error_msg + r = Reply.new + r.title = "There's no content!" + assert !r.valid? + assert r.errors.invalid?("content"), "A reply without content should mark that attribute as invalid" + assert_equal ["Empty"], r.errors["content"], "A reply without content should contain an error" + assert_equal 1, r.errors.count + end + + def test_double_attr_validation_and_error_msg + r = Reply.new + assert !r.valid? + + assert r.errors.invalid?("title"), "A reply without title should mark that attribute as invalid" + assert_equal ["Empty"], r.errors["title"], "A reply without title should contain an error" + + assert r.errors.invalid?("content"), "A reply without content should mark that attribute as invalid" + assert_equal ["Empty"], r.errors["content"], "A reply without content should contain an error" + + assert_equal 2, r.errors.count + end + + def test_single_error_per_attr_iteration + r = Reply.new + r.save + + errors = [] + r.errors.each {|attr, messages| errors << [attr.to_s, messages] } + + assert errors.include?(["title", "Empty"]) + assert errors.include?(["content", "Empty"]) + end + + def test_multiple_errors_per_attr_iteration_with_full_error_composition + r = Reply.new + r.title = "Wrong Create" + r.content = "Mismatch" + r.save + + errors = r.errors.to_a + + assert_equal "Title is Wrong Create", errors[0] + assert_equal "Title is Content Mismatch", errors[1] + assert_equal 2, r.errors.count + end + + def test_errors_on_base + r = Reply.new + r.content = "Mismatch" + r.save + r.errors.add_to_base "Reply is not dignifying" + + errors = [] + r.errors.each_full { |error| errors << error } + + assert_equal "Reply is not dignifying", r.errors.on_base + + assert errors.include?("Title Empty") + assert errors.include?("Reply is not dignifying") + assert_equal 2, r.errors.count + end + + def test_validates_each + hits = 0 + Topic.validates_each(:title, :content, [:title, :content]) do |record, attr| + record.errors.add attr, 'gotcha' + hits += 1 + end + t = Topic.new("title" => "valid", "content" => "whatever") + assert !t.save + assert_equal 4, hits + assert_equal %w(gotcha gotcha), t.errors[:title] + assert_equal %w(gotcha gotcha), t.errors[:content] + end + + def test_validate_block + Topic.validate { |topic| topic.errors.add("title", "will never be valid") } + t = Topic.create("title" => "Title", "content" => "whatever") + assert !t.valid? + assert t.errors[:title].any? + assert_equal ["will never be valid"], t.errors["title"] + end + + def test_invalid_validator + Topic.validate 3 + assert_raise(ArgumentError) { t = Topic.create } + end + + def test_errors_to_xml + r = Reply.new :title => "Wrong Create" + assert !r.valid? + xml = r.errors.to_xml(:skip_instruct => true) + assert_equal "", xml.first(8) + assert xml.include?("Title is Wrong Create") + assert xml.include?("Content Empty") + end + + def test_validation_order + Topic.validates_presence_of :title + Topic.validates_length_of :title, :minimum => 2 + + t = Topic.new("title" => "") + assert !t.valid? + assert_equal "can't be blank", t.errors["title"].first + end + + def test_invalid_should_be_the_opposite_of_valid + Topic.validates_presence_of :title + + t = Topic.new + assert t.invalid? + assert t.errors.invalid?(:title) + + t.title = 'Things are going to change' + assert !t.invalid? + end +end \ No newline at end of file diff --git a/activemodel/test/models/developer.rb b/activemodel/test/models/developer.rb new file mode 100644 index 0000000000..a839fe1135 --- /dev/null +++ b/activemodel/test/models/developer.rb @@ -0,0 +1,4 @@ +class Developer < ActiveRecord::Base + validates_inclusion_of :salary, :in => 50000..200000 + validates_length_of :name, :within => 3..20 +end diff --git a/activemodel/test/models/reply.rb b/activemodel/test/models/reply.rb new file mode 100644 index 0000000000..cfe256034c --- /dev/null +++ b/activemodel/test/models/reply.rb @@ -0,0 +1,30 @@ +require 'models/topic' + +class Reply < Topic + validate :errors_on_empty_content + validate_on_create :title_is_wrong_create + + attr_accessible :title, :author_name, :author_email_address, :written_on, :content, :last_read + + def validate + errors[:title] << "Empty" unless attribute_present?("title") + end + + def errors_on_empty_content + errors[:content] << "Empty" unless attribute_present?("content") + end + + def validate_on_create + if attribute_present?("title") && attribute_present?("content") && content == "Mismatch" + errors[:title] << "is Content Mismatch" + end + end + + def title_is_wrong_create + errors[:title] << "is Wrong Create" if attribute_present?("title") && title == "Wrong Create" + end + + def validate_on_update + errors[:title] << "is Wrong Update" if attribute_present?("title") && title == "Wrong Update" + end +end diff --git a/activemodel/test/models/topic.rb b/activemodel/test/models/topic.rb new file mode 100644 index 0000000000..1350aa17e7 --- /dev/null +++ b/activemodel/test/models/topic.rb @@ -0,0 +1,9 @@ +class Topic < ActiveRecord::Base + def condition_is_true + true + end + + def condition_is_true_but_its_not + false + end +end -- cgit v1.2.3 From d01e639dafece0cbae08512f4645bcee7a5a8224 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 20 Mar 2009 15:33:40 +0000 Subject: Remove unused columns from the ActiveModel test schema --- activemodel/test/schema.rb | 9 --------- 1 file changed, 9 deletions(-) (limited to 'activemodel/test') diff --git a/activemodel/test/schema.rb b/activemodel/test/schema.rb index 3f289c63f8..f7fe31dc4e 100644 --- a/activemodel/test/schema.rb +++ b/activemodel/test/schema.rb @@ -2,21 +2,12 @@ ActiveRecord::Schema.define do create_table :topics, :force => true do |t| t.string :title t.string :author_name - t.string :author_email_address - t.datetime :written_on - t.time :bonus_time - t.date :last_read t.text :content t.boolean :approved, :default => true - t.integer :replies_count, :default => 0 - t.integer :parent_id t.string :type end create_table :developers, :force => true do |t| t.string :name - t.integer :salary, :default => 70000 - t.datetime :created_at - t.datetime :updated_at end end -- cgit v1.2.3 From 4367f39dea7eedb1bf6e7f52b4522c695befe1da Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 20 Mar 2009 16:02:12 +0000 Subject: TestDatabase -> TestsDatabase --- activemodel/test/cases/test_database.rb | 31 ---------------------- activemodel/test/cases/tests_database.rb | 31 ++++++++++++++++++++++ .../validations/acceptance_validation_test.rb | 4 +-- .../validations/conditional_validation_test.rb | 4 +-- .../validations/confirmation_validation_test.rb | 4 +-- .../cases/validations/exclusion_validation_test.rb | 4 +-- .../cases/validations/format_validation_test.rb | 4 +-- .../test/cases/validations/i18n_validation_test.rb | 2 +- .../cases/validations/inclusion_validation_test.rb | 4 +-- .../cases/validations/length_validation_test.rb | 4 +-- .../validations/numericality_validation_test.rb | 4 +-- .../cases/validations/presence_validation_test.rb | 4 +-- activemodel/test/cases/validations_test.rb | 4 +-- 13 files changed, 52 insertions(+), 52 deletions(-) delete mode 100644 activemodel/test/cases/test_database.rb create mode 100644 activemodel/test/cases/tests_database.rb (limited to 'activemodel/test') diff --git a/activemodel/test/cases/test_database.rb b/activemodel/test/cases/test_database.rb deleted file mode 100644 index 509383ec59..0000000000 --- a/activemodel/test/cases/test_database.rb +++ /dev/null @@ -1,31 +0,0 @@ -require 'logger' - -$:.unshift(File.dirname(__FILE__) + '/../../../activerecord/lib') -require 'active_record' -require 'active_record/fixtures' - -module ActiveModel - module TestDatabase - def self.included(base) - ActiveRecord::Base.logger = Logger.new("debug.log") - ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:') - - base.send :include, ActiveRecord::TestFixtures - base.setup :setup_database - end - - def setup_database - unless $schema_file_loaded - begin - # TODO : May the better way be with you - original, $stdout = $stdout, StringIO.new - load(SCHEMA_FILE) - ensure - $stdout = original - end - - $schema_file_loaded = true - end - end - end -end diff --git a/activemodel/test/cases/tests_database.rb b/activemodel/test/cases/tests_database.rb new file mode 100644 index 0000000000..cb5cda98f5 --- /dev/null +++ b/activemodel/test/cases/tests_database.rb @@ -0,0 +1,31 @@ +require 'logger' + +$:.unshift(File.dirname(__FILE__) + '/../../../activerecord/lib') +require 'active_record' +require 'active_record/fixtures' + +module ActiveModel + module TestsDatabase + def self.included(base) + ActiveRecord::Base.logger = Logger.new("debug.log") + ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:') + + base.send :include, ActiveRecord::TestFixtures + base.setup :setup_database + end + + def setup_database + unless $schema_file_loaded + begin + # TODO : May the better way be with you + original, $stdout = $stdout, StringIO.new + load(SCHEMA_FILE) + ensure + $stdout = original + end + + $schema_file_loaded = true + end + end + end +end diff --git a/activemodel/test/cases/validations/acceptance_validation_test.rb b/activemodel/test/cases/validations/acceptance_validation_test.rb index f5f0279554..b24da3b334 100644 --- a/activemodel/test/cases/validations/acceptance_validation_test.rb +++ b/activemodel/test/cases/validations/acceptance_validation_test.rb @@ -1,13 +1,13 @@ # encoding: utf-8 require 'cases/helper' -require 'cases/test_database' +require 'cases/tests_database' require 'models/topic' require 'models/reply' require 'models/developer' class AcceptanceValidationTest < ActiveModel::TestCase - include ActiveModel::TestDatabase + include ActiveModel::TestsDatabase include ActiveModel::ValidationsRepairHelper repair_validations(Topic) diff --git a/activemodel/test/cases/validations/conditional_validation_test.rb b/activemodel/test/cases/validations/conditional_validation_test.rb index d4cb3555f3..72b4800dce 100644 --- a/activemodel/test/cases/validations/conditional_validation_test.rb +++ b/activemodel/test/cases/validations/conditional_validation_test.rb @@ -1,11 +1,11 @@ # encoding: utf-8 require 'cases/helper' -require 'cases/test_database' +require 'cases/tests_database' require 'models/topic' class ConditionalValidationTest < ActiveModel::TestCase - include ActiveModel::TestDatabase + include ActiveModel::TestsDatabase include ActiveModel::ValidationsRepairHelper repair_validations(Topic) diff --git a/activemodel/test/cases/validations/confirmation_validation_test.rb b/activemodel/test/cases/validations/confirmation_validation_test.rb index c3caa63d0b..3b4b27df39 100644 --- a/activemodel/test/cases/validations/confirmation_validation_test.rb +++ b/activemodel/test/cases/validations/confirmation_validation_test.rb @@ -1,12 +1,12 @@ # encoding: utf-8 require 'cases/helper' -require 'cases/test_database' +require 'cases/tests_database' require 'models/topic' require 'models/developer' class ConfirmationValidationTest < ActiveModel::TestCase - include ActiveModel::TestDatabase + include ActiveModel::TestsDatabase include ActiveModel::ValidationsRepairHelper repair_validations(Topic) diff --git a/activemodel/test/cases/validations/exclusion_validation_test.rb b/activemodel/test/cases/validations/exclusion_validation_test.rb index 2e3da3c079..b9b53ffb23 100644 --- a/activemodel/test/cases/validations/exclusion_validation_test.rb +++ b/activemodel/test/cases/validations/exclusion_validation_test.rb @@ -1,11 +1,11 @@ # encoding: utf-8 require 'cases/helper' -require 'cases/test_database' +require 'cases/tests_database' require 'models/topic' class ExclusionValidationTest < ActiveModel::TestCase - include ActiveModel::TestDatabase + include ActiveModel::TestsDatabase include ActiveModel::ValidationsRepairHelper repair_validations(Topic) diff --git a/activemodel/test/cases/validations/format_validation_test.rb b/activemodel/test/cases/validations/format_validation_test.rb index 9a7a93a6c6..adf90adf6f 100644 --- a/activemodel/test/cases/validations/format_validation_test.rb +++ b/activemodel/test/cases/validations/format_validation_test.rb @@ -1,11 +1,11 @@ # encoding: utf-8 require 'cases/helper' -require 'cases/test_database' +require 'cases/tests_database' require 'models/topic' class PresenceValidationTest < ActiveModel::TestCase - include ActiveModel::TestDatabase + include ActiveModel::TestsDatabase include ActiveModel::ValidationsRepairHelper repair_validations(Topic) diff --git a/activemodel/test/cases/validations/i18n_validation_test.rb b/activemodel/test/cases/validations/i18n_validation_test.rb index 2b2e52ca82..52a6c87668 100644 --- a/activemodel/test/cases/validations/i18n_validation_test.rb +++ b/activemodel/test/cases/validations/i18n_validation_test.rb @@ -3,7 +3,7 @@ require 'models/topic' require 'models/reply' class I18nValidationTest < ActiveModel::TestCase - include ActiveModel::TestDatabase + include ActiveModel::TestsDatabase def setup reset_callbacks Topic diff --git a/activemodel/test/cases/validations/inclusion_validation_test.rb b/activemodel/test/cases/validations/inclusion_validation_test.rb index 7b2020c719..8d81cca96b 100644 --- a/activemodel/test/cases/validations/inclusion_validation_test.rb +++ b/activemodel/test/cases/validations/inclusion_validation_test.rb @@ -1,11 +1,11 @@ # encoding: utf-8 require 'cases/helper' -require 'cases/test_database' +require 'cases/tests_database' require 'models/topic' class InclusionValidationTest < ActiveModel::TestCase - include ActiveModel::TestDatabase + include ActiveModel::TestsDatabase include ActiveModel::ValidationsRepairHelper repair_validations(Topic) diff --git a/activemodel/test/cases/validations/length_validation_test.rb b/activemodel/test/cases/validations/length_validation_test.rb index daca363b57..9c4639a141 100644 --- a/activemodel/test/cases/validations/length_validation_test.rb +++ b/activemodel/test/cases/validations/length_validation_test.rb @@ -1,11 +1,11 @@ # encoding: utf-8 require 'cases/helper' -require 'cases/test_database' +require 'cases/tests_database' require 'models/topic' class LengthValidationTest < ActiveModel::TestCase - include ActiveModel::TestDatabase + include ActiveModel::TestsDatabase include ActiveModel::ValidationsRepairHelper repair_validations(Topic) diff --git a/activemodel/test/cases/validations/numericality_validation_test.rb b/activemodel/test/cases/validations/numericality_validation_test.rb index 3a30c0cec1..0fd87313e0 100644 --- a/activemodel/test/cases/validations/numericality_validation_test.rb +++ b/activemodel/test/cases/validations/numericality_validation_test.rb @@ -1,12 +1,12 @@ # encoding: utf-8 require 'cases/helper' -require 'cases/test_database' +require 'cases/tests_database' require 'models/topic' require 'models/developer' class NumericalityValidationTest < ActiveModel::TestCase - include ActiveModel::TestDatabase + include ActiveModel::TestsDatabase include ActiveModel::ValidationsRepairHelper repair_validations(Topic) diff --git a/activemodel/test/cases/validations/presence_validation_test.rb b/activemodel/test/cases/validations/presence_validation_test.rb index 5bf29be491..994066095b 100644 --- a/activemodel/test/cases/validations/presence_validation_test.rb +++ b/activemodel/test/cases/validations/presence_validation_test.rb @@ -1,11 +1,11 @@ # encoding: utf-8 require 'cases/helper' -require 'cases/test_database' +require 'cases/tests_database' require 'models/topic' class PresenceValidationTest < ActiveModel::TestCase - include ActiveModel::TestDatabase + include ActiveModel::TestsDatabase include ActiveModel::ValidationsRepairHelper repair_validations(Topic) diff --git a/activemodel/test/cases/validations_test.rb b/activemodel/test/cases/validations_test.rb index a7269522eb..5b4f955eae 100644 --- a/activemodel/test/cases/validations_test.rb +++ b/activemodel/test/cases/validations_test.rb @@ -1,13 +1,13 @@ # encoding: utf-8 require 'cases/helper' -require 'cases/test_database' +require 'cases/tests_database' require 'models/topic' require 'models/reply' require 'models/developer' class ValidationsTest < ActiveModel::TestCase - include ActiveModel::TestDatabase + include ActiveModel::TestsDatabase include ActiveModel::ValidationsRepairHelper fixtures :topics, :developers -- cgit v1.2.3 From 37283a6aaec244cb484e24b3e9ff165e89eadd64 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 20 Mar 2009 17:36:22 +0000 Subject: Deprecate Error#on(attribute) in favour of Errors#[attribute] --- .../cases/validations/exclusion_validation_test.rb | 4 +- .../cases/validations/format_validation_test.rb | 2 +- .../test/cases/validations/i18n_validation_test.rb | 60 +++++++++++----------- .../cases/validations/inclusion_validation_test.rb | 8 +-- .../cases/validations/length_validation_test.rb | 52 +++++++++---------- .../validations/numericality_validation_test.rb | 4 +- activemodel/test/cases/validations_test.rb | 26 +++++++++- 7 files changed, 90 insertions(+), 66 deletions(-) (limited to 'activemodel/test') diff --git a/activemodel/test/cases/validations/exclusion_validation_test.rb b/activemodel/test/cases/validations/exclusion_validation_test.rb index b9b53ffb23..ad3123c1e4 100644 --- a/activemodel/test/cases/validations/exclusion_validation_test.rb +++ b/activemodel/test/cases/validations/exclusion_validation_test.rb @@ -24,7 +24,7 @@ class ExclusionValidationTest < ActiveModel::TestCase t = Topic.create("title" => "monkey") assert !t.valid? - assert t.errors.on(:title) - assert_equal "option monkey is restricted", t.errors.on(:title) + assert t.errors[:title].any? + assert_equal ["option monkey is restricted"], t.errors[:title] end end diff --git a/activemodel/test/cases/validations/format_validation_test.rb b/activemodel/test/cases/validations/format_validation_test.rb index adf90adf6f..301cb36e61 100644 --- a/activemodel/test/cases/validations/format_validation_test.rb +++ b/activemodel/test/cases/validations/format_validation_test.rb @@ -66,7 +66,7 @@ class PresenceValidationTest < ActiveModel::TestCase def test_validate_format_with_formatted_message Topic.validates_format_of(:title, :with => /^Valid Title$/, :message => "can't be {{value}}") t = Topic.create(:title => 'Invalid title') - assert_equal "can't be Invalid title", t.errors.on(:title) + assert_equal ["can't be Invalid title"], t.errors[:title] end def test_validates_format_of_with_custom_error_using_quotes diff --git a/activemodel/test/cases/validations/i18n_validation_test.rb b/activemodel/test/cases/validations/i18n_validation_test.rb index 52a6c87668..8eedf76d41 100644 --- a/activemodel/test/cases/validations/i18n_validation_test.rb +++ b/activemodel/test/cases/validations/i18n_validation_test.rb @@ -389,7 +389,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_confirmation_of :title @topic.title_confirmation = 'foo' @topic.valid? - assert_equal 'custom message', @topic.errors.on(:title) + assert_equal ['custom message'], @topic.errors[:title] end def test_validates_confirmation_of_finds_global_default_translation @@ -398,7 +398,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_confirmation_of :title @topic.title_confirmation = 'foo' @topic.valid? - assert_equal 'global message', @topic.errors.on(:title) + assert_equal ['global message'], @topic.errors[:title] end # validates_acceptance_of w/o mocha @@ -409,7 +409,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_acceptance_of :title, :allow_nil => false @topic.valid? - assert_equal 'custom message', @topic.errors.on(:title) + assert_equal ['custom message'], @topic.errors[:title] end def test_validates_acceptance_of_finds_global_default_translation @@ -417,7 +417,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_acceptance_of :title, :allow_nil => false @topic.valid? - assert_equal 'global message', @topic.errors.on(:title) + assert_equal ['global message'], @topic.errors[:title] end # validates_presence_of w/o mocha @@ -428,7 +428,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_presence_of :title @topic.valid? - assert_equal 'custom message', @topic.errors.on(:title) + assert_equal ['custom message'], @topic.errors[:title] end def test_validates_presence_of_finds_global_default_translation @@ -436,7 +436,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_presence_of :title @topic.valid? - assert_equal 'global message', @topic.errors.on(:title) + assert_equal ['global message'], @topic.errors[:title] end # validates_length_of :within w/o mocha @@ -447,7 +447,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_length_of :title, :within => 3..5 @topic.valid? - assert_equal 'custom message', @topic.errors.on(:title) + assert_equal ['custom message'], @topic.errors[:title] end def test_validates_length_of_within_finds_global_default_translation @@ -455,7 +455,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_length_of :title, :within => 3..5 @topic.valid? - assert_equal 'global message', @topic.errors.on(:title) + assert_equal ['global message'], @topic.errors[:title] end # validates_length_of :is w/o mocha @@ -466,7 +466,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_length_of :title, :is => 5 @topic.valid? - assert_equal 'custom message', @topic.errors.on(:title) + assert_equal ['custom message'], @topic.errors[:title] end def test_validates_length_of_is_finds_global_default_translation @@ -474,7 +474,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_length_of :title, :is => 5 @topic.valid? - assert_equal 'global message', @topic.errors.on(:title) + assert_equal ['global message'], @topic.errors[:title] end def test_validates_length_of_is_finds_custom_model_key_translation @@ -483,7 +483,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_length_of :title, :is => 5 @topic.valid? - assert_equal 'custom message', @topic.errors.on(:title) + assert_equal ['custom message'], @topic.errors[:title] end def test_validates_length_of_is_finds_global_default_translation @@ -491,7 +491,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_length_of :title, :is => 5 @topic.valid? - assert_equal 'global message', @topic.errors.on(:title) + assert_equal ['global message'], @topic.errors[:title] end @@ -503,7 +503,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/ @topic.valid? - assert_equal 'custom message', @topic.errors.on(:title) + assert_equal ['custom message'], @topic.errors[:title] end def test_validates_format_of_finds_global_default_translation @@ -511,7 +511,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/ @topic.valid? - assert_equal 'global message', @topic.errors.on(:title) + assert_equal ['global message'], @topic.errors[:title] end # validates_inclusion_of w/o mocha @@ -522,7 +522,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_inclusion_of :title, :in => %w(a b c) @topic.valid? - assert_equal 'custom message', @topic.errors.on(:title) + assert_equal ['custom message'], @topic.errors[:title] end def test_validates_inclusion_of_finds_global_default_translation @@ -530,7 +530,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_inclusion_of :title, :in => %w(a b c) @topic.valid? - assert_equal 'global message', @topic.errors.on(:title) + assert_equal ['global message'], @topic.errors[:title] end # validates_exclusion_of w/o mocha @@ -542,7 +542,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_exclusion_of :title, :in => %w(a b c) @topic.title = 'a' @topic.valid? - assert_equal 'custom message', @topic.errors.on(:title) + assert_equal ['custom message'], @topic.errors[:title] end def test_validates_exclusion_of_finds_global_default_translation @@ -551,7 +551,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_exclusion_of :title, :in => %w(a b c) @topic.title = 'a' @topic.valid? - assert_equal 'global message', @topic.errors.on(:title) + assert_equal ['global message'], @topic.errors[:title] end # validates_numericality_of without :only_integer w/o mocha @@ -563,7 +563,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_numericality_of :title @topic.title = 'a' @topic.valid? - assert_equal 'custom message', @topic.errors.on(:title) + assert_equal ['custom message'], @topic.errors[:title] end def test_validates_numericality_of_finds_global_default_translation @@ -572,7 +572,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_numericality_of :title, :only_integer => true @topic.title = 'a' @topic.valid? - assert_equal 'global message', @topic.errors.on(:title) + assert_equal ['global message'], @topic.errors[:title] end # validates_numericality_of with :only_integer w/o mocha @@ -584,7 +584,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_numericality_of :title, :only_integer => true @topic.title = 'a' @topic.valid? - assert_equal 'custom message', @topic.errors.on(:title) + assert_equal ['custom message'], @topic.errors[:title] end def test_validates_numericality_of_only_integer_finds_global_default_translation @@ -593,7 +593,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_numericality_of :title, :only_integer => true @topic.title = 'a' @topic.valid? - assert_equal 'global message', @topic.errors.on(:title) + assert_equal ['global message'], @topic.errors[:title] end # validates_numericality_of :odd w/o mocha @@ -605,7 +605,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_numericality_of :title, :only_integer => true, :odd => true @topic.title = 0 @topic.valid? - assert_equal 'custom message', @topic.errors.on(:title) + assert_equal ['custom message'], @topic.errors[:title] end def test_validates_numericality_of_odd_finds_global_default_translation @@ -614,7 +614,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_numericality_of :title, :only_integer => true, :odd => true @topic.title = 0 @topic.valid? - assert_equal 'global message', @topic.errors.on(:title) + assert_equal ['global message'], @topic.errors[:title] end # validates_numericality_of :less_than w/o mocha @@ -626,7 +626,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0 @topic.title = 1 @topic.valid? - assert_equal 'custom message', @topic.errors.on(:title) + assert_equal ['custom message'], @topic.errors[:title] end def test_validates_numericality_of_less_than_finds_global_default_translation @@ -635,7 +635,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0 @topic.title = 1 @topic.valid? - assert_equal 'global message', @topic.errors.on(:title) + assert_equal ['global message'], @topic.errors[:title] end def test_validations_with_message_symbol_must_translate @@ -643,7 +643,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_presence_of :title, :message => :custom_error @topic.title = nil @topic.valid? - assert_equal "I am a custom error", @topic.errors.on(:title) + assert_equal ["I am a custom error"], @topic.errors[:title] end def test_validates_with_message_symbol_must_translate_per_attribute @@ -651,7 +651,7 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_presence_of :title, :message => :custom_error @topic.title = nil @topic.valid? - assert_equal "I am a custom error", @topic.errors.on(:title) + assert_equal ["I am a custom error"], @topic.errors[:title] end def test_validates_with_message_symbol_must_translate_per_model @@ -659,14 +659,14 @@ class I18nValidationTest < ActiveModel::TestCase Topic.validates_presence_of :title, :message => :custom_error @topic.title = nil @topic.valid? - assert_equal "I am a custom error", @topic.errors.on(:title) + assert_equal ["I am a custom error"], @topic.errors[:title] end def test_validates_with_message_string Topic.validates_presence_of :title, :message => "I am a custom error" @topic.title = nil @topic.valid? - assert_equal "I am a custom error", @topic.errors.on(:title) + assert_equal ["I am a custom error"], @topic.errors[:title] end end \ No newline at end of file diff --git a/activemodel/test/cases/validations/inclusion_validation_test.rb b/activemodel/test/cases/validations/inclusion_validation_test.rb index 8d81cca96b..678461a037 100644 --- a/activemodel/test/cases/validations/inclusion_validation_test.rb +++ b/activemodel/test/cases/validations/inclusion_validation_test.rb @@ -21,8 +21,8 @@ class InclusionValidationTest < ActiveModel::TestCase assert t.valid? t.title = "uhoh" assert !t.valid? - assert t.errors.on(:title) - assert_equal "is not included in the list", t.errors.on(:title) + assert t.errors[:title].any? + assert_equal ["is not included in the list"], t.errors[:title] assert_raise(ArgumentError) { Topic.validates_inclusion_of( :title, :in => nil ) } assert_raise(ArgumentError) { Topic.validates_inclusion_of( :title, :in => 0) } @@ -47,8 +47,8 @@ class InclusionValidationTest < ActiveModel::TestCase t = Topic.create("title" => "uhoh", "content" => "abc") assert !t.valid? - assert t.errors.on(:title) - assert_equal "option uhoh is not in the list", t.errors.on(:title) + assert t.errors[:title].any? + assert_equal ["option uhoh is not in the list"], t.errors[:title] end def test_validates_inclusion_of_with_custom_error_using_quotes diff --git a/activemodel/test/cases/validations/length_validation_test.rb b/activemodel/test/cases/validations/length_validation_test.rb index 9c4639a141..e84e2815fa 100644 --- a/activemodel/test/cases/validations/length_validation_test.rb +++ b/activemodel/test/cases/validations/length_validation_test.rb @@ -36,17 +36,17 @@ class LengthValidationTest < ActiveModel::TestCase t.title = "not" assert !t.valid? - assert t.errors.on(:title) - assert_equal "is too short (minimum is 5 characters)", t.errors.on(:title) + assert t.errors[:title].any? + assert_equal ["is too short (minimum is 5 characters)"], t.errors[:title] t.title = "" assert !t.valid? - assert t.errors.on(:title) - assert_equal "is too short (minimum is 5 characters)", t.errors.on(:title) + assert t.errors[:title].any? + assert_equal ["is too short (minimum is 5 characters)"], t.errors[:title] t.title = nil assert !t.valid? - assert t.errors.on(:title) + assert t.errors[:title].any? assert_equal ["is too short (minimum is 5 characters)"], t.errors["title"] end @@ -68,8 +68,8 @@ class LengthValidationTest < ActiveModel::TestCase t.title = "notvalid" assert !t.valid? - assert t.errors.on(:title) - assert_equal "is too long (maximum is 5 characters)", t.errors.on(:title) + assert t.errors[:title].any? + assert_equal ["is too long (maximum is 5 characters)"], t.errors[:title] t.title = "" assert t.valid? @@ -93,14 +93,14 @@ class LengthValidationTest < ActiveModel::TestCase t = Topic.new("title" => "a!", "content" => "I'm ooooooooh so very long") assert !t.valid? - assert_equal "is too short (minimum is 3 characters)", t.errors.on(:title) - assert_equal "is too long (maximum is 5 characters)", t.errors.on(:content) + assert_equal ["is too short (minimum is 3 characters)"], t.errors[:title] + assert_equal ["is too long (maximum is 5 characters)"], t.errors[:content] t.title = nil t.content = nil assert !t.valid? - assert_equal "is too short (minimum is 3 characters)", t.errors.on(:title) - assert_equal "is too short (minimum is 3 characters)", t.errors.on(:content) + assert_equal ["is too short (minimum is 3 characters)"], t.errors[:title] + assert_equal ["is too short (minimum is 3 characters)"], t.errors[:content] t.title = "abe" t.content = "mad" @@ -122,8 +122,8 @@ class LengthValidationTest < ActiveModel::TestCase t = Topic.create("title" => "thisisnotvalid", "content" => "whatever") assert !t.save - assert t.errors.on(:title) - assert_equal "my string is too long: 10", t.errors.on(:title) + assert t.errors[:title].any? + assert_equal ["my string is too long: 10"], t.errors[:title] t.title = "butthisis" assert t.save @@ -143,17 +143,17 @@ class LengthValidationTest < ActiveModel::TestCase t = Topic.create("title" => "vali", "content" => "whatever") assert !t.save - assert t.errors.on(:title) + assert t.errors[:title].any? t.title = "not" assert !t.save - assert t.errors.on(:title) - assert_equal "my string is too short: 5", t.errors.on(:title) + assert t.errors[:title].any? + assert_equal ["my string is too short: 5"], t.errors[:title] t.title = "valid" t.content = "andthisistoolong" assert !t.save - assert t.errors.on(:content) + assert t.errors[:content].any? t.content = "iamfine" assert t.save @@ -167,8 +167,8 @@ class LengthValidationTest < ActiveModel::TestCase t.title = "notvalid" assert !t.valid? - assert t.errors.on(:title) - assert_equal "is the wrong length (should be 5 characters)", t.errors.on(:title) + assert t.errors[:title].any? + assert_equal ["is the wrong length (should be 5 characters)"], t.errors[:title] t.title = "" assert !t.valid? @@ -208,7 +208,7 @@ class LengthValidationTest < ActiveModel::TestCase t = Topic.create(:title => 'too short') assert !t.valid? - assert_equal 'tu est trops petit hombre 10', t.errors.on(:title) + assert_equal ['tu est trops petit hombre 10'], t.errors[:title] end def test_validates_length_of_nasty_params @@ -226,23 +226,23 @@ class LengthValidationTest < ActiveModel::TestCase Topic.validates_length_of( :title, :minimum=>5, :message=>"boo {{count}}" ) t = Topic.create("title" => "uhoh", "content" => "whatever") assert !t.valid? - assert t.errors.on(:title) - assert_equal "boo 5", t.errors.on(:title) + assert t.errors[:title].any? + assert_equal ["boo 5"], t.errors[:title] end def test_validates_length_of_custom_errors_for_minimum_with_too_short Topic.validates_length_of( :title, :minimum=>5, :too_short=>"hoo {{count}}" ) t = Topic.create("title" => "uhoh", "content" => "whatever") assert !t.valid? - assert t.errors.on(:title) - assert_equal "hoo 5", t.errors.on(:title) + assert t.errors[:title].any? + assert_equal ["hoo 5"], t.errors[:title] end def test_validates_length_of_custom_errors_for_maximum_with_message Topic.validates_length_of( :title, :maximum=>5, :message=>"boo {{count}}" ) t = Topic.create("title" => "uhohuhoh", "content" => "whatever") assert !t.valid? - assert t.errors.on(:title) + assert t.errors[:title].any? assert_equal ["boo 5"], t.errors[:title] end @@ -374,7 +374,7 @@ class LengthValidationTest < ActiveModel::TestCase t.title = "1二三4" assert !t.save assert t.errors[:title].any? - assert_equal "短すぎます: 5", t.errors.on(:title) + assert_equal ["短すぎます: 5"], t.errors[:title] t.title = "一二三四五六七八九十A" assert !t.save diff --git a/activemodel/test/cases/validations/numericality_validation_test.rb b/activemodel/test/cases/validations/numericality_validation_test.rb index 0fd87313e0..53d3621149 100644 --- a/activemodel/test/cases/validations/numericality_validation_test.rb +++ b/activemodel/test/cases/validations/numericality_validation_test.rb @@ -110,13 +110,13 @@ class NumericalityValidationTest < ActiveModel::TestCase topic = Topic.new("title" => "numeric test", "approved" => 10) assert !topic.valid? - assert_equal "smaller than 4", topic.errors.on(:approved) + assert_equal ["smaller than 4"], topic.errors[:approved] Topic.validates_numericality_of :approved, :greater_than => 4, :message => "greater than {{count}}" topic = Topic.new("title" => "numeric test", "approved" => 1) assert !topic.valid? - assert_equal "greater than 4", topic.errors.on(:approved) + assert_equal ["greater than 4"], topic.errors[:approved] end private diff --git a/activemodel/test/cases/validations_test.rb b/activemodel/test/cases/validations_test.rb index 5b4f955eae..6c1b382cf2 100644 --- a/activemodel/test/cases/validations_test.rb +++ b/activemodel/test/cases/validations_test.rb @@ -80,7 +80,7 @@ class ValidationsTest < ActiveModel::TestCase errors = [] r.errors.each_full { |error| errors << error } - assert_equal "Reply is not dignifying", r.errors.on_base + assert_equal ["Reply is not dignifying"], r.errors[:base] assert errors.include?("Title Empty") assert errors.include?("Reply is not dignifying") @@ -141,4 +141,28 @@ class ValidationsTest < ActiveModel::TestCase t.title = 'Things are going to change' assert !t.invalid? end + + def test_deprecated_error_messages_on + Topic.validates_presence_of :title + + t = Topic.new + assert t.invalid? + + [:title, "title"].each do |attribute| + assert_deprecated { assert_equal "can't be blank", t.errors.on(attribute) } + end + + Topic.validates_each(:title) do |record, attribute| + record.errors[attribute] << "invalid" + end + + assert t.invalid? + + [:title, "title"].each do |attribute| + assert_deprecated do + assert t.errors.on(attribute).include?("invalid") + assert t.errors.on(attribute).include?("can't be blank") + end + end + end end \ No newline at end of file -- cgit v1.2.3 From 4a582aa7caf31faa87f435b8ae39fdb85fab1042 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 20 Mar 2009 17:49:57 +0000 Subject: Use mattr_accessor in TestsDatabase instead of setup method --- activemodel/test/cases/tests_database.rb | 36 ++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'activemodel/test') diff --git a/activemodel/test/cases/tests_database.rb b/activemodel/test/cases/tests_database.rb index cb5cda98f5..0f4475fa2d 100644 --- a/activemodel/test/cases/tests_database.rb +++ b/activemodel/test/cases/tests_database.rb @@ -6,25 +6,35 @@ require 'active_record/fixtures' module ActiveModel module TestsDatabase + mattr_accessor :connected + def self.included(base) - ActiveRecord::Base.logger = Logger.new("debug.log") - ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:') + unless self.connected + setup_connection + setup_schema + end base.send :include, ActiveRecord::TestFixtures - base.setup :setup_database end - def setup_database - unless $schema_file_loaded - begin - # TODO : May the better way be with you - original, $stdout = $stdout, StringIO.new - load(SCHEMA_FILE) - ensure - $stdout = original - end + def self.setup_schema + original, $stdout = $stdout, StringIO.new + load(SCHEMA_FILE) + ensure + $stdout = original + self.connected = true + end - $schema_file_loaded = true + def self.setup_connection + defaults = { :database => ':memory:' } + begin + adapter = defined?(JRUBY_VERSION) ? 'jdbcsqlite3' : 'sqlite3' + options = defaults.merge :adapter => adapter, :timeout => 500 + ActiveRecord::Base.establish_connection(options) + rescue Exception + $stderr.puts 'SQLite 3 unavailable; trying SQLite 2.' + options = defaults.merge :adapter => 'sqlite' + ActiveRecord::Base.establish_connection(options) end end end -- cgit v1.2.3 From 7d187c193c96c10398934851fb660b6b3cfcd240 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 20 Mar 2009 18:07:35 +0000 Subject: Validation tests arent using any fixtures --- activemodel/test/cases/validations_test.rb | 2 -- 1 file changed, 2 deletions(-) (limited to 'activemodel/test') diff --git a/activemodel/test/cases/validations_test.rb b/activemodel/test/cases/validations_test.rb index 6c1b382cf2..a5dd7af04d 100644 --- a/activemodel/test/cases/validations_test.rb +++ b/activemodel/test/cases/validations_test.rb @@ -10,8 +10,6 @@ class ValidationsTest < ActiveModel::TestCase include ActiveModel::TestsDatabase include ActiveModel::ValidationsRepairHelper - fixtures :topics, :developers - # Most of the tests mess with the validations of Topic, so lets repair it all the time. # Other classes we mess with will be dealt with in the specific tests repair_validations(Topic) -- cgit v1.2.3 From 08a99d0eac9370b590220953283475e00e3183e6 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 20 Mar 2009 21:40:37 +0000 Subject: Add I18n translations to ActiveModel and move more AR specific parts to ActiveRecord::Validations --- .../i18n_generate_message_validation_test.rb | 82 +-- .../test/cases/validations/i18n_validation_test.rb | 631 +++++++++------------ .../cases/validations/length_validation_test.rb | 11 - activemodel/test/models/person.rb | 5 + 4 files changed, 325 insertions(+), 404 deletions(-) create mode 100644 activemodel/test/models/person.rb (limited to 'activemodel/test') diff --git a/activemodel/test/cases/validations/i18n_generate_message_validation_test.rb b/activemodel/test/cases/validations/i18n_generate_message_validation_test.rb index 871c69d06d..37bba5e95e 100644 --- a/activemodel/test/cases/validations/i18n_generate_message_validation_test.rb +++ b/activemodel/test/cases/validations/i18n_generate_message_validation_test.rb @@ -1,13 +1,19 @@ require "cases/helper" -require 'models/topic' -require 'models/reply' +require 'cases/tests_database' + +require 'models/person' class I18nGenerateMessageValidationTest < Test::Unit::TestCase def setup - reset_callbacks Topic - @topic = Topic.new + reset_callbacks Person + @person = Person.new + + @old_load_path, @old_backend = I18n.load_path, I18n.backend + I18n.load_path.clear + I18n.backend = I18n::Backend::Simple.new + I18n.backend.store_translations :'en', { - :activerecord => { + :activemodel => { :errors => { :messages => { :inclusion => "is not included in the list", @@ -34,141 +40,143 @@ class I18nGenerateMessageValidationTest < Test::Unit::TestCase } end + def teardown + I18n.load_path.replace @old_load_path + I18n.backend = @old_backend + end + def reset_callbacks(*models) models.each do |model| model.instance_variable_set("@validate_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - model.instance_variable_set("@validate_on_create_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - model.instance_variable_set("@validate_on_update_callbacks", ActiveSupport::Callbacks::CallbackChain.new) end end # validates_inclusion_of: generate_message(attr_name, :inclusion, :default => configuration[:message], :value => value) def test_generate_message_inclusion_with_default_message - assert_equal 'is not included in the list', @topic.errors.generate_message(:title, :inclusion, :default => nil, :value => 'title') + assert_equal 'is not included in the list', @person.errors.generate_message(:title, :inclusion, :default => nil, :value => 'title') end def test_generate_message_inclusion_with_custom_message - assert_equal 'custom message title', @topic.errors.generate_message(:title, :inclusion, :default => 'custom message {{value}}', :value => 'title') + assert_equal 'custom message title', @person.errors.generate_message(:title, :inclusion, :default => 'custom message {{value}}', :value => 'title') end # validates_exclusion_of: generate_message(attr_name, :exclusion, :default => configuration[:message], :value => value) def test_generate_message_exclusion_with_default_message - assert_equal 'is reserved', @topic.errors.generate_message(:title, :exclusion, :default => nil, :value => 'title') + assert_equal 'is reserved', @person.errors.generate_message(:title, :exclusion, :default => nil, :value => 'title') end def test_generate_message_exclusion_with_custom_message - assert_equal 'custom message title', @topic.errors.generate_message(:title, :exclusion, :default => 'custom message {{value}}', :value => 'title') + assert_equal 'custom message title', @person.errors.generate_message(:title, :exclusion, :default => 'custom message {{value}}', :value => 'title') end # validates_associated: generate_message(attr_name, :invalid, :default => configuration[:message], :value => value) # validates_format_of: generate_message(attr_name, :invalid, :default => configuration[:message], :value => value) def test_generate_message_invalid_with_default_message - assert_equal 'is invalid', @topic.errors.generate_message(:title, :invalid, :default => nil, :value => 'title') + assert_equal 'is invalid', @person.errors.generate_message(:title, :invalid, :default => nil, :value => 'title') end def test_generate_message_invalid_with_custom_message - assert_equal 'custom message title', @topic.errors.generate_message(:title, :invalid, :default => 'custom message {{value}}', :value => 'title') + assert_equal 'custom message title', @person.errors.generate_message(:title, :invalid, :default => 'custom message {{value}}', :value => 'title') end # validates_confirmation_of: generate_message(attr_name, :confirmation, :default => configuration[:message]) def test_generate_message_confirmation_with_default_message - assert_equal "doesn't match confirmation", @topic.errors.generate_message(:title, :confirmation, :default => nil) + assert_equal "doesn't match confirmation", @person.errors.generate_message(:title, :confirmation, :default => nil) end def test_generate_message_confirmation_with_custom_message - assert_equal 'custom message', @topic.errors.generate_message(:title, :confirmation, :default => 'custom message') + assert_equal 'custom message', @person.errors.generate_message(:title, :confirmation, :default => 'custom message') end # validates_acceptance_of: generate_message(attr_name, :accepted, :default => configuration[:message]) def test_generate_message_accepted_with_default_message - assert_equal "must be accepted", @topic.errors.generate_message(:title, :accepted, :default => nil) + assert_equal "must be accepted", @person.errors.generate_message(:title, :accepted, :default => nil) end def test_generate_message_accepted_with_custom_message - assert_equal 'custom message', @topic.errors.generate_message(:title, :accepted, :default => 'custom message') + assert_equal 'custom message', @person.errors.generate_message(:title, :accepted, :default => 'custom message') end # add_on_empty: generate_message(attr, :empty, :default => custom_message) def test_generate_message_empty_with_default_message - assert_equal "can't be empty", @topic.errors.generate_message(:title, :empty, :default => nil) + assert_equal "can't be empty", @person.errors.generate_message(:title, :empty, :default => nil) end def test_generate_message_empty_with_custom_message - assert_equal 'custom message', @topic.errors.generate_message(:title, :empty, :default => 'custom message') + assert_equal 'custom message', @person.errors.generate_message(:title, :empty, :default => 'custom message') end # add_on_blank: generate_message(attr, :blank, :default => custom_message) def test_generate_message_blank_with_default_message - assert_equal "can't be blank", @topic.errors.generate_message(:title, :blank, :default => nil) + assert_equal "can't be blank", @person.errors.generate_message(:title, :blank, :default => nil) end def test_generate_message_blank_with_custom_message - assert_equal 'custom message', @topic.errors.generate_message(:title, :blank, :default => 'custom message') + assert_equal 'custom message', @person.errors.generate_message(:title, :blank, :default => 'custom message') end # validates_length_of: generate_message(attr, :too_long, :default => options[:too_long], :count => option_value.end) def test_generate_message_too_long_with_default_message - assert_equal "is too long (maximum is 10 characters)", @topic.errors.generate_message(:title, :too_long, :default => nil, :count => 10) + assert_equal "is too long (maximum is 10 characters)", @person.errors.generate_message(:title, :too_long, :default => nil, :count => 10) end def test_generate_message_too_long_with_custom_message - assert_equal 'custom message 10', @topic.errors.generate_message(:title, :too_long, :default => 'custom message {{count}}', :count => 10) + assert_equal 'custom message 10', @person.errors.generate_message(:title, :too_long, :default => 'custom message {{count}}', :count => 10) end # validates_length_of: generate_message(attr, :too_short, :default => options[:too_short], :count => option_value.begin) def test_generate_message_too_short_with_default_message - assert_equal "is too short (minimum is 10 characters)", @topic.errors.generate_message(:title, :too_short, :default => nil, :count => 10) + assert_equal "is too short (minimum is 10 characters)", @person.errors.generate_message(:title, :too_short, :default => nil, :count => 10) end def test_generate_message_too_short_with_custom_message - assert_equal 'custom message 10', @topic.errors.generate_message(:title, :too_short, :default => 'custom message {{count}}', :count => 10) + assert_equal 'custom message 10', @person.errors.generate_message(:title, :too_short, :default => 'custom message {{count}}', :count => 10) end # validates_length_of: generate_message(attr, key, :default => custom_message, :count => option_value) def test_generate_message_wrong_length_with_default_message - assert_equal "is the wrong length (should be 10 characters)", @topic.errors.generate_message(:title, :wrong_length, :default => nil, :count => 10) + assert_equal "is the wrong length (should be 10 characters)", @person.errors.generate_message(:title, :wrong_length, :default => nil, :count => 10) end def test_generate_message_wrong_length_with_custom_message - assert_equal 'custom message 10', @topic.errors.generate_message(:title, :wrong_length, :default => 'custom message {{count}}', :count => 10) + assert_equal 'custom message 10', @person.errors.generate_message(:title, :wrong_length, :default => 'custom message {{count}}', :count => 10) end # validates_numericality_of: generate_message(attr_name, :not_a_number, :value => raw_value, :default => configuration[:message]) def test_generate_message_not_a_number_with_default_message - assert_equal "is not a number", @topic.errors.generate_message(:title, :not_a_number, :default => nil, :value => 'title') + assert_equal "is not a number", @person.errors.generate_message(:title, :not_a_number, :default => nil, :value => 'title') end def test_generate_message_not_a_number_with_custom_message - assert_equal 'custom message title', @topic.errors.generate_message(:title, :not_a_number, :default => 'custom message {{value}}', :value => 'title') + assert_equal 'custom message title', @person.errors.generate_message(:title, :not_a_number, :default => 'custom message {{value}}', :value => 'title') end # validates_numericality_of: generate_message(attr_name, option, :value => raw_value, :default => configuration[:message]) def test_generate_message_greater_than_with_default_message - assert_equal "must be greater than 10", @topic.errors.generate_message(:title, :greater_than, :default => nil, :value => 'title', :count => 10) + assert_equal "must be greater than 10", @person.errors.generate_message(:title, :greater_than, :default => nil, :value => 'title', :count => 10) end def test_generate_message_greater_than_or_equal_to_with_default_message - assert_equal "must be greater than or equal to 10", @topic.errors.generate_message(:title, :greater_than_or_equal_to, :default => nil, :value => 'title', :count => 10) + assert_equal "must be greater than or equal to 10", @person.errors.generate_message(:title, :greater_than_or_equal_to, :default => nil, :value => 'title', :count => 10) end def test_generate_message_equal_to_with_default_message - assert_equal "must be equal to 10", @topic.errors.generate_message(:title, :equal_to, :default => nil, :value => 'title', :count => 10) + assert_equal "must be equal to 10", @person.errors.generate_message(:title, :equal_to, :default => nil, :value => 'title', :count => 10) end def test_generate_message_less_than_with_default_message - assert_equal "must be less than 10", @topic.errors.generate_message(:title, :less_than, :default => nil, :value => 'title', :count => 10) + assert_equal "must be less than 10", @person.errors.generate_message(:title, :less_than, :default => nil, :value => 'title', :count => 10) end def test_generate_message_less_than_or_equal_to_with_default_message - assert_equal "must be less than or equal to 10", @topic.errors.generate_message(:title, :less_than_or_equal_to, :default => nil, :value => 'title', :count => 10) + assert_equal "must be less than or equal to 10", @person.errors.generate_message(:title, :less_than_or_equal_to, :default => nil, :value => 'title', :count => 10) end def test_generate_message_odd_with_default_message - assert_equal "must be odd", @topic.errors.generate_message(:title, :odd, :default => nil, :value => 'title', :count => 10) + assert_equal "must be odd", @person.errors.generate_message(:title, :odd, :default => nil, :value => 'title', :count => 10) end def test_generate_message_even_with_default_message - assert_equal "must be even", @topic.errors.generate_message(:title, :even, :default => nil, :value => 'title', :count => 10) + assert_equal "must be even", @person.errors.generate_message(:title, :even, :default => nil, :value => 'title', :count => 10) end - end diff --git a/activemodel/test/cases/validations/i18n_validation_test.rb b/activemodel/test/cases/validations/i18n_validation_test.rb index 8eedf76d41..a1bb93b731 100644 --- a/activemodel/test/cases/validations/i18n_validation_test.rb +++ b/activemodel/test/cases/validations/i18n_validation_test.rb @@ -1,21 +1,24 @@ require "cases/helper" -require 'models/topic' -require 'models/reply' +require 'cases/tests_database' + +require 'models/person' class I18nValidationTest < ActiveModel::TestCase include ActiveModel::TestsDatabase def setup - reset_callbacks Topic - @topic = Topic.new + reset_callbacks Person + + @person = Person.new + @old_load_path, @old_backend = I18n.load_path, I18n.backend I18n.load_path.clear I18n.backend = I18n::Backend::Simple.new - I18n.backend.store_translations('en', :activerecord => {:errors => {:messages => {:custom => nil}}}) + I18n.backend.store_translations('en', :activemodel => {:errors => {:messages => {:custom => nil}}}) end def teardown - reset_callbacks Topic + reset_callbacks Person I18n.load_path.replace @old_load_path I18n.backend = @old_backend end @@ -23,14 +26,6 @@ class I18nValidationTest < ActiveModel::TestCase def reset_callbacks(*models) models.each do |model| model.instance_variable_set("@validate_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - model.instance_variable_set("@validate_on_create_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - model.instance_variable_set("@validate_on_update_callbacks", ActiveSupport::Callbacks::CallbackChain.new) - end - end - - def test_default_error_messages_is_deprecated - assert_deprecated('Errors.default_error_messages') do - ActiveModel::Errors.default_error_messages end end @@ -60,613 +55,537 @@ class I18nValidationTest < ActiveModel::TestCase end end - # ActiveModel::Errors - def test_errors_generate_message_translates_custom_model_attribute_key - - I18n.expects(:translate).with( - :topic, - { :count => 1, - :default => ['Topic'], - :scope => [:activerecord, :models] - } - ).returns('Topic') - - I18n.expects(:translate).with( - :"topic.title", - { :count => 1, - :default => ['Title'], - :scope => [:activerecord, :attributes] - } - ).returns('Title') - - I18n.expects(:translate).with( - :"models.topic.attributes.title.invalid", - :value => nil, - :scope => [:activerecord, :errors], - :default => [ - :"models.topic.invalid", - 'default from class def error 1', - :"messages.invalid"], - :attribute => "Title", - :model => "Topic" - ).returns('default from class def error 1') - - @topic.errors.generate_message :title, :invalid, :default => 'default from class def error 1' - end - - def test_errors_generate_message_translates_custom_model_attribute_keys_with_sti - - I18n.expects(:translate).with( - :reply, - { :count => 1, - :default => [:topic, 'Reply'], - :scope => [:activerecord, :models] - } - ).returns('Reply') - - I18n.expects(:translate).with( - :"reply.title", - { :count => 1, - :default => [:'topic.title', 'Title'], - :scope => [:activerecord, :attributes] - } - ).returns('Title') - - I18n.expects(:translate).with( - :"models.reply.attributes.title.invalid", - :value => nil, - :scope => [:activerecord, :errors], - :default => [ - :"models.reply.invalid", - :"models.topic.attributes.title.invalid", - :"models.topic.invalid", - 'default from class def', - :"messages.invalid"], - :model => 'Reply', - :attribute => 'Title' - ).returns("default from class def") - - Reply.new.errors.generate_message :title, :invalid, :default => 'default from class def' - - end - def test_errors_add_on_empty_generates_message - @topic.errors.expects(:generate_message).with(:title, :empty, {:default => nil}) - @topic.errors.add_on_empty :title + @person.errors.expects(:generate_message).with(:title, :empty, {:default => nil}) + @person.errors.add_on_empty :title end def test_errors_add_on_empty_generates_message_with_custom_default_message - @topic.errors.expects(:generate_message).with(:title, :empty, {:default => 'custom'}) - @topic.errors.add_on_empty :title, 'custom' + @person.errors.expects(:generate_message).with(:title, :empty, {:default => 'custom'}) + @person.errors.add_on_empty :title, 'custom' end def test_errors_add_on_blank_generates_message - @topic.errors.expects(:generate_message).with(:title, :blank, {:default => nil}) - @topic.errors.add_on_blank :title + @person.errors.expects(:generate_message).with(:title, :blank, {:default => nil}) + @person.errors.add_on_blank :title end def test_errors_add_on_blank_generates_message_with_custom_default_message - @topic.errors.expects(:generate_message).with(:title, :blank, {:default => 'custom'}) - @topic.errors.add_on_blank :title, 'custom' - end - - def test_errors_full_messages_translates_human_attribute_name_for_model_attributes - @topic.errors.add('title', 'empty') - I18n.expects(:translate).with(:"topic.title", :default => ['Title'], :scope => [:activerecord, :attributes], :count => 1).returns('Title') - @topic.errors.full_messages :locale => 'en' + @person.errors.expects(:generate_message).with(:title, :blank, {:default => 'custom'}) + @person.errors.add_on_blank :title, 'custom' end # ActiveRecord::Validations # validates_confirmation_of w/ mocha def test_validates_confirmation_of_generates_message - Topic.validates_confirmation_of :title - @topic.title_confirmation = 'foo' - @topic.errors.expects(:generate_message).with(:title, :confirmation, {:default => nil}) - @topic.valid? + Person.validates_confirmation_of :title + @person.title_confirmation = 'foo' + @person.errors.expects(:generate_message).with(:title, :confirmation, {:default => nil}) + @person.valid? end def test_validates_confirmation_of_generates_message_with_custom_default_message - Topic.validates_confirmation_of :title, :message => 'custom' - @topic.title_confirmation = 'foo' - @topic.errors.expects(:generate_message).with(:title, :confirmation, {:default => 'custom'}) - @topic.valid? + Person.validates_confirmation_of :title, :message => 'custom' + @person.title_confirmation = 'foo' + @person.errors.expects(:generate_message).with(:title, :confirmation, {:default => 'custom'}) + @person.valid? end # validates_acceptance_of w/ mocha def test_validates_acceptance_of_generates_message - Topic.validates_acceptance_of :title, :allow_nil => false - @topic.errors.expects(:generate_message).with(:title, :accepted, {:default => nil}) - @topic.valid? + Person.validates_acceptance_of :title, :allow_nil => false + @person.errors.expects(:generate_message).with(:title, :accepted, {:default => nil}) + @person.valid? end def test_validates_acceptance_of_generates_message_with_custom_default_message - Topic.validates_acceptance_of :title, :message => 'custom', :allow_nil => false - @topic.errors.expects(:generate_message).with(:title, :accepted, {:default => 'custom'}) - @topic.valid? + Person.validates_acceptance_of :title, :message => 'custom', :allow_nil => false + @person.errors.expects(:generate_message).with(:title, :accepted, {:default => 'custom'}) + @person.valid? end # validates_presence_of w/ mocha def test_validates_presence_of_generates_message - Topic.validates_presence_of :title - @topic.errors.expects(:generate_message).with(:title, :blank, {:default => nil}) - @topic.valid? + Person.validates_presence_of :title + @person.errors.expects(:generate_message).with(:title, :blank, {:default => nil}) + @person.valid? end def test_validates_presence_of_generates_message_with_custom_default_message - Topic.validates_presence_of :title, :message => 'custom' - @topic.errors.expects(:generate_message).with(:title, :blank, {:default => 'custom'}) - @topic.valid? + Person.validates_presence_of :title, :message => 'custom' + @person.errors.expects(:generate_message).with(:title, :blank, {:default => 'custom'}) + @person.valid? end def test_validates_length_of_within_generates_message_with_title_too_short - Topic.validates_length_of :title, :within => 3..5 - @topic.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => nil}) - @topic.valid? + Person.validates_length_of :title, :within => 3..5 + @person.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => nil}) + @person.valid? end def test_validates_length_of_within_generates_message_with_title_too_short_and_custom_default_message - Topic.validates_length_of :title, :within => 3..5, :too_short => 'custom' - @topic.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => 'custom'}) - @topic.valid? + Person.validates_length_of :title, :within => 3..5, :too_short => 'custom' + @person.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => 'custom'}) + @person.valid? end def test_validates_length_of_within_generates_message_with_title_too_long - Topic.validates_length_of :title, :within => 3..5 - @topic.title = 'this title is too long' - @topic.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => nil}) - @topic.valid? + Person.validates_length_of :title, :within => 3..5 + @person.title = 'this title is too long' + @person.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => nil}) + @person.valid? end def test_validates_length_of_within_generates_message_with_title_too_long_and_custom_default_message - Topic.validates_length_of :title, :within => 3..5, :too_long => 'custom' - @topic.title = 'this title is too long' - @topic.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => 'custom'}) - @topic.valid? + Person.validates_length_of :title, :within => 3..5, :too_long => 'custom' + @person.title = 'this title is too long' + @person.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => 'custom'}) + @person.valid? end # validates_length_of :within w/ mocha def test_validates_length_of_within_generates_message_with_title_too_short - Topic.validates_length_of :title, :within => 3..5 - @topic.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => nil}) - @topic.valid? + Person.validates_length_of :title, :within => 3..5 + @person.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => nil}) + @person.valid? end def test_validates_length_of_within_generates_message_with_title_too_short_and_custom_default_message - Topic.validates_length_of :title, :within => 3..5, :too_short => 'custom' - @topic.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => 'custom'}) - @topic.valid? + Person.validates_length_of :title, :within => 3..5, :too_short => 'custom' + @person.errors.expects(:generate_message).with(:title, :too_short, {:count => 3, :default => 'custom'}) + @person.valid? end def test_validates_length_of_within_generates_message_with_title_too_long - Topic.validates_length_of :title, :within => 3..5 - @topic.title = 'this title is too long' - @topic.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => nil}) - @topic.valid? + Person.validates_length_of :title, :within => 3..5 + @person.title = 'this title is too long' + @person.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => nil}) + @person.valid? end def test_validates_length_of_within_generates_message_with_title_too_long_and_custom_default_message - Topic.validates_length_of :title, :within => 3..5, :too_long => 'custom' - @topic.title = 'this title is too long' - @topic.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => 'custom'}) - @topic.valid? + Person.validates_length_of :title, :within => 3..5, :too_long => 'custom' + @person.title = 'this title is too long' + @person.errors.expects(:generate_message).with(:title, :too_long, {:count => 5, :default => 'custom'}) + @person.valid? end # validates_length_of :is w/ mocha def test_validates_length_of_is_generates_message - Topic.validates_length_of :title, :is => 5 - @topic.errors.expects(:generate_message).with(:title, :wrong_length, {:count => 5, :default => nil}) - @topic.valid? + Person.validates_length_of :title, :is => 5 + @person.errors.expects(:generate_message).with(:title, :wrong_length, {:count => 5, :default => nil}) + @person.valid? end def test_validates_length_of_is_generates_message_with_custom_default_message - Topic.validates_length_of :title, :is => 5, :message => 'custom' - @topic.errors.expects(:generate_message).with(:title, :wrong_length, {:count => 5, :default => 'custom'}) - @topic.valid? + Person.validates_length_of :title, :is => 5, :message => 'custom' + @person.errors.expects(:generate_message).with(:title, :wrong_length, {:count => 5, :default => 'custom'}) + @person.valid? end # validates_format_of w/ mocha def test_validates_format_of_generates_message - Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/ - @topic.title = '72x' - @topic.errors.expects(:generate_message).with(:title, :invalid, {:value => '72x', :default => nil}) - @topic.valid? + Person.validates_format_of :title, :with => /^[1-9][0-9]*$/ + @person.title = '72x' + @person.errors.expects(:generate_message).with(:title, :invalid, {:value => '72x', :default => nil}) + @person.valid? end def test_validates_format_of_generates_message_with_custom_default_message - Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/, :message => 'custom' - @topic.title = '72x' - @topic.errors.expects(:generate_message).with(:title, :invalid, {:value => '72x', :default => 'custom'}) - @topic.valid? + Person.validates_format_of :title, :with => /^[1-9][0-9]*$/, :message => 'custom' + @person.title = '72x' + @person.errors.expects(:generate_message).with(:title, :invalid, {:value => '72x', :default => 'custom'}) + @person.valid? end # validates_inclusion_of w/ mocha def test_validates_inclusion_of_generates_message - Topic.validates_inclusion_of :title, :in => %w(a b c) - @topic.title = 'z' - @topic.errors.expects(:generate_message).with(:title, :inclusion, {:value => 'z', :default => nil}) - @topic.valid? + Person.validates_inclusion_of :title, :in => %w(a b c) + @person.title = 'z' + @person.errors.expects(:generate_message).with(:title, :inclusion, {:value => 'z', :default => nil}) + @person.valid? end def test_validates_inclusion_of_generates_message_with_custom_default_message - Topic.validates_inclusion_of :title, :in => %w(a b c), :message => 'custom' - @topic.title = 'z' - @topic.errors.expects(:generate_message).with(:title, :inclusion, {:value => 'z', :default => 'custom'}) - @topic.valid? + Person.validates_inclusion_of :title, :in => %w(a b c), :message => 'custom' + @person.title = 'z' + @person.errors.expects(:generate_message).with(:title, :inclusion, {:value => 'z', :default => 'custom'}) + @person.valid? end # validates_exclusion_of w/ mocha def test_validates_exclusion_of_generates_message - Topic.validates_exclusion_of :title, :in => %w(a b c) - @topic.title = 'a' - @topic.errors.expects(:generate_message).with(:title, :exclusion, {:value => 'a', :default => nil}) - @topic.valid? + Person.validates_exclusion_of :title, :in => %w(a b c) + @person.title = 'a' + @person.errors.expects(:generate_message).with(:title, :exclusion, {:value => 'a', :default => nil}) + @person.valid? end def test_validates_exclusion_of_generates_message_with_custom_default_message - Topic.validates_exclusion_of :title, :in => %w(a b c), :message => 'custom' - @topic.title = 'a' - @topic.errors.expects(:generate_message).with(:title, :exclusion, {:value => 'a', :default => 'custom'}) - @topic.valid? + Person.validates_exclusion_of :title, :in => %w(a b c), :message => 'custom' + @person.title = 'a' + @person.errors.expects(:generate_message).with(:title, :exclusion, {:value => 'a', :default => 'custom'}) + @person.valid? end # validates_numericality_of without :only_integer w/ mocha def test_validates_numericality_of_generates_message - Topic.validates_numericality_of :title - @topic.title = 'a' - @topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => nil}) - @topic.valid? + Person.validates_numericality_of :title + @person.title = 'a' + @person.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => nil}) + @person.valid? end def test_validates_numericality_of_generates_message_with_custom_default_message - Topic.validates_numericality_of :title, :message => 'custom' - @topic.title = 'a' - @topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => 'custom'}) - @topic.valid? + Person.validates_numericality_of :title, :message => 'custom' + @person.title = 'a' + @person.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => 'custom'}) + @person.valid? end # validates_numericality_of with :only_integer w/ mocha def test_validates_numericality_of_only_integer_generates_message - Topic.validates_numericality_of :title, :only_integer => true - @topic.title = 'a' - @topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => nil}) - @topic.valid? + Person.validates_numericality_of :title, :only_integer => true + @person.title = 'a' + @person.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => nil}) + @person.valid? end def test_validates_numericality_of_only_integer_generates_message_with_custom_default_message - Topic.validates_numericality_of :title, :only_integer => true, :message => 'custom' - @topic.title = 'a' - @topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => 'custom'}) - @topic.valid? + Person.validates_numericality_of :title, :only_integer => true, :message => 'custom' + @person.title = 'a' + @person.errors.expects(:generate_message).with(:title, :not_a_number, {:value => 'a', :default => 'custom'}) + @person.valid? end # validates_numericality_of :odd w/ mocha def test_validates_numericality_of_odd_generates_message - Topic.validates_numericality_of :title, :only_integer => true, :odd => true - @topic.title = 0 - @topic.errors.expects(:generate_message).with(:title, :odd, {:value => 0, :default => nil}) - @topic.valid? + Person.validates_numericality_of :title, :only_integer => true, :odd => true + @person.title = 0 + @person.errors.expects(:generate_message).with(:title, :odd, {:value => 0, :default => nil}) + @person.valid? end def test_validates_numericality_of_odd_generates_message_with_custom_default_message - Topic.validates_numericality_of :title, :only_integer => true, :odd => true, :message => 'custom' - @topic.title = 0 - @topic.errors.expects(:generate_message).with(:title, :odd, {:value => 0, :default => 'custom'}) - @topic.valid? + Person.validates_numericality_of :title, :only_integer => true, :odd => true, :message => 'custom' + @person.title = 0 + @person.errors.expects(:generate_message).with(:title, :odd, {:value => 0, :default => 'custom'}) + @person.valid? end # validates_numericality_of :less_than w/ mocha def test_validates_numericality_of_less_than_generates_message - Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0 - @topic.title = 1 - @topic.errors.expects(:generate_message).with(:title, :less_than, {:value => 1, :count => 0, :default => nil}) - @topic.valid? + Person.validates_numericality_of :title, :only_integer => true, :less_than => 0 + @person.title = 1 + @person.errors.expects(:generate_message).with(:title, :less_than, {:value => 1, :count => 0, :default => nil}) + @person.valid? end def test_validates_numericality_of_odd_generates_message_with_custom_default_message - Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0, :message => 'custom' - @topic.title = 1 - @topic.errors.expects(:generate_message).with(:title, :less_than, {:value => 1, :count => 0, :default => 'custom'}) - @topic.valid? + Person.validates_numericality_of :title, :only_integer => true, :less_than => 0, :message => 'custom' + @person.title = 1 + @person.errors.expects(:generate_message).with(:title, :less_than, {:value => 1, :count => 0, :default => 'custom'}) + @person.valid? end # validates_confirmation_of w/o mocha def test_validates_confirmation_of_finds_custom_model_key_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:confirmation => 'custom message'}}}}}} - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:confirmation => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:confirmation => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:confirmation => 'global message'}}} - Topic.validates_confirmation_of :title - @topic.title_confirmation = 'foo' - @topic.valid? - assert_equal ['custom message'], @topic.errors[:title] + Person.validates_confirmation_of :title + @person.title_confirmation = 'foo' + @person.valid? + assert_equal ['custom message'], @person.errors[:title] end def test_validates_confirmation_of_finds_global_default_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:confirmation => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:confirmation => 'global message'}}} - Topic.validates_confirmation_of :title - @topic.title_confirmation = 'foo' - @topic.valid? - assert_equal ['global message'], @topic.errors[:title] + Person.validates_confirmation_of :title + @person.title_confirmation = 'foo' + @person.valid? + assert_equal ['global message'], @person.errors[:title] end # validates_acceptance_of w/o mocha def test_validates_acceptance_of_finds_custom_model_key_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:accepted => 'custom message'}}}}}} - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:accepted => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:accepted => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:accepted => 'global message'}}} - Topic.validates_acceptance_of :title, :allow_nil => false - @topic.valid? - assert_equal ['custom message'], @topic.errors[:title] + Person.validates_acceptance_of :title, :allow_nil => false + @person.valid? + assert_equal ['custom message'], @person.errors[:title] end def test_validates_acceptance_of_finds_global_default_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:accepted => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:accepted => 'global message'}}} - Topic.validates_acceptance_of :title, :allow_nil => false - @topic.valid? - assert_equal ['global message'], @topic.errors[:title] + Person.validates_acceptance_of :title, :allow_nil => false + @person.valid? + assert_equal ['global message'], @person.errors[:title] end # validates_presence_of w/o mocha def test_validates_presence_of_finds_custom_model_key_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:blank => 'custom message'}}}}}} - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:blank => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:blank => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:blank => 'global message'}}} - Topic.validates_presence_of :title - @topic.valid? - assert_equal ['custom message'], @topic.errors[:title] + Person.validates_presence_of :title + @person.valid? + assert_equal ['custom message'], @person.errors[:title] end def test_validates_presence_of_finds_global_default_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:blank => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:blank => 'global message'}}} - Topic.validates_presence_of :title - @topic.valid? - assert_equal ['global message'], @topic.errors[:title] + Person.validates_presence_of :title + @person.valid? + assert_equal ['global message'], @person.errors[:title] end # validates_length_of :within w/o mocha def test_validates_length_of_within_finds_custom_model_key_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:too_short => 'custom message'}}}}}} - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:too_short => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:too_short => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:too_short => 'global message'}}} - Topic.validates_length_of :title, :within => 3..5 - @topic.valid? - assert_equal ['custom message'], @topic.errors[:title] + Person.validates_length_of :title, :within => 3..5 + @person.valid? + assert_equal ['custom message'], @person.errors[:title] end def test_validates_length_of_within_finds_global_default_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:too_short => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:too_short => 'global message'}}} - Topic.validates_length_of :title, :within => 3..5 - @topic.valid? - assert_equal ['global message'], @topic.errors[:title] + Person.validates_length_of :title, :within => 3..5 + @person.valid? + assert_equal ['global message'], @person.errors[:title] end # validates_length_of :is w/o mocha def test_validates_length_of_is_finds_custom_model_key_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}} - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:wrong_length => 'global message'}}} - Topic.validates_length_of :title, :is => 5 - @topic.valid? - assert_equal ['custom message'], @topic.errors[:title] + Person.validates_length_of :title, :is => 5 + @person.valid? + assert_equal ['custom message'], @person.errors[:title] end def test_validates_length_of_is_finds_global_default_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:wrong_length => 'global message'}}} - Topic.validates_length_of :title, :is => 5 - @topic.valid? - assert_equal ['global message'], @topic.errors[:title] + Person.validates_length_of :title, :is => 5 + @person.valid? + assert_equal ['global message'], @person.errors[:title] end def test_validates_length_of_is_finds_custom_model_key_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}} - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:wrong_length => 'global message'}}} - Topic.validates_length_of :title, :is => 5 - @topic.valid? - assert_equal ['custom message'], @topic.errors[:title] + Person.validates_length_of :title, :is => 5 + @person.valid? + assert_equal ['custom message'], @person.errors[:title] end def test_validates_length_of_is_finds_global_default_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:wrong_length => 'global message'}}} - Topic.validates_length_of :title, :is => 5 - @topic.valid? - assert_equal ['global message'], @topic.errors[:title] + Person.validates_length_of :title, :is => 5 + @person.valid? + assert_equal ['global message'], @person.errors[:title] end # validates_format_of w/o mocha def test_validates_format_of_finds_custom_model_key_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:invalid => 'custom message'}}}}}} - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:invalid => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:invalid => 'global message'}}} - Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/ - @topic.valid? - assert_equal ['custom message'], @topic.errors[:title] + Person.validates_format_of :title, :with => /^[1-9][0-9]*$/ + @person.valid? + assert_equal ['custom message'], @person.errors[:title] end def test_validates_format_of_finds_global_default_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:invalid => 'global message'}}} - Topic.validates_format_of :title, :with => /^[1-9][0-9]*$/ - @topic.valid? - assert_equal ['global message'], @topic.errors[:title] + Person.validates_format_of :title, :with => /^[1-9][0-9]*$/ + @person.valid? + assert_equal ['global message'], @person.errors[:title] end # validates_inclusion_of w/o mocha def test_validates_inclusion_of_finds_custom_model_key_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:inclusion => 'custom message'}}}}}} - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:inclusion => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:inclusion => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:inclusion => 'global message'}}} - Topic.validates_inclusion_of :title, :in => %w(a b c) - @topic.valid? - assert_equal ['custom message'], @topic.errors[:title] + Person.validates_inclusion_of :title, :in => %w(a b c) + @person.valid? + assert_equal ['custom message'], @person.errors[:title] end def test_validates_inclusion_of_finds_global_default_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:inclusion => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:inclusion => 'global message'}}} - Topic.validates_inclusion_of :title, :in => %w(a b c) - @topic.valid? - assert_equal ['global message'], @topic.errors[:title] + Person.validates_inclusion_of :title, :in => %w(a b c) + @person.valid? + assert_equal ['global message'], @person.errors[:title] end # validates_exclusion_of w/o mocha def test_validates_exclusion_of_finds_custom_model_key_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:exclusion => 'custom message'}}}}}} - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:exclusion => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:exclusion => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:exclusion => 'global message'}}} - Topic.validates_exclusion_of :title, :in => %w(a b c) - @topic.title = 'a' - @topic.valid? - assert_equal ['custom message'], @topic.errors[:title] + Person.validates_exclusion_of :title, :in => %w(a b c) + @person.title = 'a' + @person.valid? + assert_equal ['custom message'], @person.errors[:title] end def test_validates_exclusion_of_finds_global_default_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:exclusion => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:exclusion => 'global message'}}} - Topic.validates_exclusion_of :title, :in => %w(a b c) - @topic.title = 'a' - @topic.valid? - assert_equal ['global message'], @topic.errors[:title] + Person.validates_exclusion_of :title, :in => %w(a b c) + @person.title = 'a' + @person.valid? + assert_equal ['global message'], @person.errors[:title] end # validates_numericality_of without :only_integer w/o mocha def test_validates_numericality_of_finds_custom_model_key_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}} - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:not_a_number => 'global message'}}} - Topic.validates_numericality_of :title - @topic.title = 'a' - @topic.valid? - assert_equal ['custom message'], @topic.errors[:title] + Person.validates_numericality_of :title + @person.title = 'a' + @person.valid? + assert_equal ['custom message'], @person.errors[:title] end def test_validates_numericality_of_finds_global_default_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:not_a_number => 'global message'}}} - Topic.validates_numericality_of :title, :only_integer => true - @topic.title = 'a' - @topic.valid? - assert_equal ['global message'], @topic.errors[:title] + Person.validates_numericality_of :title, :only_integer => true + @person.title = 'a' + @person.valid? + assert_equal ['global message'], @person.errors[:title] end # 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', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}} - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:not_a_number => 'global message'}}} - Topic.validates_numericality_of :title, :only_integer => true - @topic.title = 'a' - @topic.valid? - assert_equal ['custom message'], @topic.errors[:title] + Person.validates_numericality_of :title, :only_integer => true + @person.title = 'a' + @person.valid? + assert_equal ['custom message'], @person.errors[:title] end def test_validates_numericality_of_only_integer_finds_global_default_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:not_a_number => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:not_a_number => 'global message'}}} - Topic.validates_numericality_of :title, :only_integer => true - @topic.title = 'a' - @topic.valid? - assert_equal ['global message'], @topic.errors[:title] + Person.validates_numericality_of :title, :only_integer => true + @person.title = 'a' + @person.valid? + assert_equal ['global message'], @person.errors[:title] end # validates_numericality_of :odd w/o mocha def test_validates_numericality_of_odd_finds_custom_model_key_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:odd => 'custom message'}}}}}} - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:odd => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:odd => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:odd => 'global message'}}} - Topic.validates_numericality_of :title, :only_integer => true, :odd => true - @topic.title = 0 - @topic.valid? - assert_equal ['custom message'], @topic.errors[:title] + Person.validates_numericality_of :title, :only_integer => true, :odd => true + @person.title = 0 + @person.valid? + assert_equal ['custom message'], @person.errors[:title] end def test_validates_numericality_of_odd_finds_global_default_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:odd => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:odd => 'global message'}}} - Topic.validates_numericality_of :title, :only_integer => true, :odd => true - @topic.title = 0 - @topic.valid? - assert_equal ['global message'], @topic.errors[:title] + Person.validates_numericality_of :title, :only_integer => true, :odd => true + @person.title = 0 + @person.valid? + assert_equal ['global message'], @person.errors[:title] end # 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', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:less_than => 'custom message'}}}}}} - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:less_than => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:less_than => 'custom message'}}}}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:less_than => 'global message'}}} - Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0 - @topic.title = 1 - @topic.valid? - assert_equal ['custom message'], @topic.errors[:title] + Person.validates_numericality_of :title, :only_integer => true, :less_than => 0 + @person.title = 1 + @person.valid? + assert_equal ['custom message'], @person.errors[:title] end def test_validates_numericality_of_less_than_finds_global_default_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:less_than => 'global message'}}} + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:less_than => 'global message'}}} - Topic.validates_numericality_of :title, :only_integer => true, :less_than => 0 - @topic.title = 1 - @topic.valid? - assert_equal ['global message'], @topic.errors[:title] + Person.validates_numericality_of :title, :only_integer => true, :less_than => 0 + @person.title = 1 + @person.valid? + assert_equal ['global message'], @person.errors[:title] end def test_validations_with_message_symbol_must_translate - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:custom_error => "I am a custom error"}}} - Topic.validates_presence_of :title, :message => :custom_error - @topic.title = nil - @topic.valid? - assert_equal ["I am a custom error"], @topic.errors[:title] + I18n.backend.store_translations 'en', :activemodel => {:errors => {:messages => {:custom_error => "I am a custom error"}}} + Person.validates_presence_of :title, :message => :custom_error + @person.title = nil + @person.valid? + assert_equal ["I am a custom error"], @person.errors[:title] end def test_validates_with_message_symbol_must_translate_per_attribute - I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:custom_error => "I am a custom error"}}}}}} - Topic.validates_presence_of :title, :message => :custom_error - @topic.title = nil - @topic.valid? - assert_equal ["I am a custom error"], @topic.errors[:title] + 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? + assert_equal ["I am a custom error"], @person.errors[:title] end def test_validates_with_message_symbol_must_translate_per_model - I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:custom_error => "I am a custom error"}}}} - Topic.validates_presence_of :title, :message => :custom_error - @topic.title = nil - @topic.valid? - assert_equal ["I am a custom error"], @topic.errors[:title] + 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? + assert_equal ["I am a custom error"], @person.errors[:title] end def test_validates_with_message_string - Topic.validates_presence_of :title, :message => "I am a custom error" - @topic.title = nil - @topic.valid? - assert_equal ["I am a custom error"], @topic.errors[:title] + Person.validates_presence_of :title, :message => "I am a custom error" + @person.title = nil + @person.valid? + assert_equal ["I am a custom error"], @person.errors[:title] end end \ No newline at end of file diff --git a/activemodel/test/cases/validations/length_validation_test.rb b/activemodel/test/cases/validations/length_validation_test.rb index e84e2815fa..ab725d9e1f 100644 --- a/activemodel/test/cases/validations/length_validation_test.rb +++ b/activemodel/test/cases/validations/length_validation_test.rb @@ -200,17 +200,6 @@ class LengthValidationTest < ActiveModel::TestCase end end - def test_validates_length_with_globally_modified_error_message - ActiveSupport::Deprecation.silence do - ActiveModel::Errors.default_error_messages[:too_short] = 'tu est trops petit hombre {{count}}' - end - Topic.validates_length_of :title, :minimum => 10 - t = Topic.create(:title => 'too short') - assert !t.valid? - - assert_equal ['tu est trops petit hombre 10'], t.errors[:title] - end - def test_validates_length_of_nasty_params assert_raise(ArgumentError) { Topic.validates_length_of(:title, :minimum=>6, :maximum=>9) } assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within=>6, :maximum=>9) } diff --git a/activemodel/test/models/person.rb b/activemodel/test/models/person.rb new file mode 100644 index 0000000000..6f787d9d3d --- /dev/null +++ b/activemodel/test/models/person.rb @@ -0,0 +1,5 @@ +class Person + include ActiveModel::Validations + + attr_accessor :title +end -- cgit v1.2.3 From 6173e5bfaec44729ecabc2e6e05aa2608a85981f Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 20 Mar 2009 22:21:27 +0000 Subject: Add ActiveModel::Validations tests for regular ruby classes --- .../validations/acceptance_validation_test.rb | 25 +++++++---- .../validations/confirmation_validation_test.rb | 17 +++++++ .../cases/validations/exclusion_validation_test.rb | 16 +++++++ .../cases/validations/format_validation_test.rb | 17 +++++++ .../cases/validations/inclusion_validation_test.rb | 17 +++++++ .../cases/validations/length_validation_test.rb | 17 +++++++ .../validations/numericality_validation_test.rb | 52 ++++++++++++++-------- .../cases/validations/presence_validation_test.rb | 16 +++++++ activemodel/test/models/developer.rb | 2 + activemodel/test/models/person.rb | 2 +- activemodel/test/schema.rb | 13 +++--- 11 files changed, 160 insertions(+), 34 deletions(-) (limited to 'activemodel/test') diff --git a/activemodel/test/cases/validations/acceptance_validation_test.rb b/activemodel/test/cases/validations/acceptance_validation_test.rb index b24da3b334..88e5fdb358 100644 --- a/activemodel/test/cases/validations/acceptance_validation_test.rb +++ b/activemodel/test/cases/validations/acceptance_validation_test.rb @@ -5,6 +5,7 @@ require 'cases/tests_database' require 'models/topic' require 'models/reply' require 'models/developer' +require 'models/person' class AcceptanceValidationTest < ActiveModel::TestCase include ActiveModel::TestsDatabase @@ -52,15 +53,6 @@ class AcceptanceValidationTest < ActiveModel::TestCase assert t.save end - def test_validates_acceptance_of_as_database_column - repair_validations(Reply) do - Reply.validates_acceptance_of(:author_name) - - reply = Reply.create("author_name" => "Dan Brown") - assert_equal "Dan Brown", reply["author_name"] - end - end - def test_validates_acceptance_of_with_custom_error_using_quotes repair_validations(Developer) do Developer.validates_acceptance_of :salary, :message=> "This string contains 'single' and \"double\" quotes" @@ -70,4 +62,19 @@ class AcceptanceValidationTest < ActiveModel::TestCase assert_equal "This string contains 'single' and \"double\" quotes", d.errors[:salary].last end end + + def test_validates_acceptance_of_for_ruby_class + repair_validations(Person) do + Person.validates_acceptance_of :karma + + p = Person.new + p.karma = "" + + assert p.invalid? + assert_equal ["must be accepted"], p.errors[:karma] + + p.karma = "1" + assert p.valid? + end + end end diff --git a/activemodel/test/cases/validations/confirmation_validation_test.rb b/activemodel/test/cases/validations/confirmation_validation_test.rb index 3b4b27df39..1d6f2a6ec5 100644 --- a/activemodel/test/cases/validations/confirmation_validation_test.rb +++ b/activemodel/test/cases/validations/confirmation_validation_test.rb @@ -4,6 +4,7 @@ require 'cases/tests_database' require 'models/topic' require 'models/developer' +require 'models/person' class ConfirmationValidationTest < ActiveModel::TestCase include ActiveModel::TestsDatabase @@ -48,4 +49,20 @@ class ConfirmationValidationTest < ActiveModel::TestCase assert_equal ["confirm 'single' and \"double\" quotes"], d.errors[:name] end end + + def test_validates_confirmation_of_for_ruby_class + repair_validations(Person) do + Person.validates_confirmation_of :karma + + p = Person.new + p.karma_confirmation = "None" + assert p.invalid? + + assert_equal ["doesn't match confirmation"], p.errors[:karma] + + p.karma = "None" + assert p.valid? + end + end + end diff --git a/activemodel/test/cases/validations/exclusion_validation_test.rb b/activemodel/test/cases/validations/exclusion_validation_test.rb index ad3123c1e4..584f009e84 100644 --- a/activemodel/test/cases/validations/exclusion_validation_test.rb +++ b/activemodel/test/cases/validations/exclusion_validation_test.rb @@ -3,6 +3,7 @@ require 'cases/helper' require 'cases/tests_database' require 'models/topic' +require 'models/person' class ExclusionValidationTest < ActiveModel::TestCase include ActiveModel::TestsDatabase @@ -27,4 +28,19 @@ class ExclusionValidationTest < ActiveModel::TestCase assert t.errors[:title].any? assert_equal ["option monkey is restricted"], t.errors[:title] end + + def test_validates_exclusion_of_for_ruby_class + repair_validations(Person) do + Person.validates_exclusion_of :karma, :in => %w( abe monkey ) + + p = Person.new + p.karma = "abe" + assert p.invalid? + + assert_equal ["is reserved"], p.errors[:karma] + + p.karma = "Lifo" + assert p.valid? + end + end end diff --git a/activemodel/test/cases/validations/format_validation_test.rb b/activemodel/test/cases/validations/format_validation_test.rb index 301cb36e61..2c06a9dd02 100644 --- a/activemodel/test/cases/validations/format_validation_test.rb +++ b/activemodel/test/cases/validations/format_validation_test.rb @@ -3,6 +3,8 @@ require 'cases/helper' require 'cases/tests_database' require 'models/topic' +require 'models/developer' +require 'models/person' class PresenceValidationTest < ActiveModel::TestCase include ActiveModel::TestsDatabase @@ -78,4 +80,19 @@ class PresenceValidationTest < ActiveModel::TestCase assert_equal ["format 'single' and \"double\" quotes"], d.errors[:name] end end + + def test_validates_format_of_for_ruby_class + repair_validations(Person) do + Person.validates_format_of :karma, :with => /\A\d+\Z/ + + p = Person.new + p.karma = "Pixies" + assert p.invalid? + + assert_equal ["is invalid"], p.errors[:karma] + + p.karma = "1234" + assert p.valid? + end + end end diff --git a/activemodel/test/cases/validations/inclusion_validation_test.rb b/activemodel/test/cases/validations/inclusion_validation_test.rb index 678461a037..bc1b0365d2 100644 --- a/activemodel/test/cases/validations/inclusion_validation_test.rb +++ b/activemodel/test/cases/validations/inclusion_validation_test.rb @@ -3,6 +3,8 @@ require 'cases/helper' require 'cases/tests_database' require 'models/topic' +require 'models/developer' +require 'models/person' class InclusionValidationTest < ActiveModel::TestCase include ActiveModel::TestsDatabase @@ -60,4 +62,19 @@ class InclusionValidationTest < ActiveModel::TestCase assert_equal "This string contains 'single' and \"double\" quotes", d.errors[:salary].last end end + + def test_validates_inclusion_of_for_ruby_class + repair_validations(Person) do + Person.validates_inclusion_of :karma, :in => %w( abe monkey ) + + p = Person.new + p.karma = "Lifo" + assert p.invalid? + + assert_equal ["is not included in the list"], p.errors[:karma] + + p.karma = "monkey" + assert p.valid? + end + end end diff --git a/activemodel/test/cases/validations/length_validation_test.rb b/activemodel/test/cases/validations/length_validation_test.rb index ab725d9e1f..4a2f72feab 100644 --- a/activemodel/test/cases/validations/length_validation_test.rb +++ b/activemodel/test/cases/validations/length_validation_test.rb @@ -3,6 +3,8 @@ require 'cases/helper' require 'cases/tests_database' require 'models/topic' +require 'models/developer' +require 'models/person' class LengthValidationTest < ActiveModel::TestCase include ActiveModel::TestsDatabase @@ -429,4 +431,19 @@ class LengthValidationTest < ActiveModel::TestCase assert_equal ["This string contains 'single' and \"double\" quotes"], d.errors[:name] end end + + def test_validates_length_of_for_ruby_class + repair_validations(Person) do + Person.validates_length_of :karma, :minimum => 5 + + p = Person.new + p.karma = "Pix" + assert p.invalid? + + assert_equal ["is too short (minimum is 5 characters)"], p.errors[:karma] + + p.karma = "The Smiths" + assert p.valid? + end + end end diff --git a/activemodel/test/cases/validations/numericality_validation_test.rb b/activemodel/test/cases/validations/numericality_validation_test.rb index 53d3621149..0af6eb69ce 100644 --- a/activemodel/test/cases/validations/numericality_validation_test.rb +++ b/activemodel/test/cases/validations/numericality_validation_test.rb @@ -4,6 +4,7 @@ require 'cases/tests_database' require 'models/topic' require 'models/developer' +require 'models/person' class NumericalityValidationTest < ActiveModel::TestCase include ActiveModel::TestsDatabase @@ -119,6 +120,39 @@ class NumericalityValidationTest < ActiveModel::TestCase assert_equal ["greater than 4"], topic.errors[:approved] end + def test_numericality_with_getter_method + repair_validations(Developer) do + Developer.validates_numericality_of( :salary ) + developer = Developer.new("name" => "michael", "salary" => nil) + developer.instance_eval("def salary; read_attribute('salary') ? read_attribute('salary') : 100000; end") + assert developer.valid? + end + end + + def test_numericality_with_allow_nil_and_getter_method + repair_validations(Developer) do + Developer.validates_numericality_of( :salary, :allow_nil => true) + developer = Developer.new("name" => "michael", "salary" => nil) + developer.instance_eval("def salary; read_attribute('salary') ? read_attribute('salary') : 100000; end") + assert developer.valid? + end + end + + def test_validates_numericality_of_for_ruby_class + repair_validations(Person) do + Person.validates_numericality_of :karma, :allow_nil => false + + p = Person.new + p.karma = "Pix" + assert p.invalid? + + assert_equal ["is not a number"], p.errors[:karma] + + p.karma = "1234" + assert p.valid? + end + end + private def invalid!(values, error = nil) @@ -142,22 +176,4 @@ class NumericalityValidationTest < ActiveModel::TestCase yield topic, value end end - - def test_numericality_with_getter_method - repair_validations(Developer) do - Developer.validates_numericality_of( :salary ) - developer = Developer.new("name" => "michael", "salary" => nil) - developer.instance_eval("def salary; read_attribute('salary') ? read_attribute('salary') : 100000; end") - assert developer.valid? - end - end - - def test_numericality_with_allow_nil_and_getter_method - repair_validations(Developer) do - Developer.validates_numericality_of( :salary, :allow_nil => true) - developer = Developer.new("name" => "michael", "salary" => nil) - developer.instance_eval("def salary; read_attribute('salary') ? read_attribute('salary') : 100000; end") - assert developer.valid? - end - end end diff --git a/activemodel/test/cases/validations/presence_validation_test.rb b/activemodel/test/cases/validations/presence_validation_test.rb index 994066095b..f6bed4903a 100644 --- a/activemodel/test/cases/validations/presence_validation_test.rb +++ b/activemodel/test/cases/validations/presence_validation_test.rb @@ -3,6 +3,8 @@ require 'cases/helper' require 'cases/tests_database' require 'models/topic' +require 'models/developer' +require 'models/person' class PresenceValidationTest < ActiveModel::TestCase include ActiveModel::TestsDatabase @@ -38,4 +40,18 @@ class PresenceValidationTest < ActiveModel::TestCase assert_equal ["This string contains 'single' and \"double\" quotes"], d.errors[:non_existent] end end + + def test_validates_presence_of_for_ruby_class + repair_validations(Person) do + Person.validates_presence_of :karma + + p = Person.new + assert p.invalid? + + assert_equal ["can't be blank"], p.errors[:karma] + + p.karma = "Cold" + assert p.valid? + end + end end diff --git a/activemodel/test/models/developer.rb b/activemodel/test/models/developer.rb index a839fe1135..5e6eefeed1 100644 --- a/activemodel/test/models/developer.rb +++ b/activemodel/test/models/developer.rb @@ -1,4 +1,6 @@ class Developer < ActiveRecord::Base validates_inclusion_of :salary, :in => 50000..200000 validates_length_of :name, :within => 3..20 + + attr_accessor :name_confirmation end diff --git a/activemodel/test/models/person.rb b/activemodel/test/models/person.rb index 6f787d9d3d..d98420f900 100644 --- a/activemodel/test/models/person.rb +++ b/activemodel/test/models/person.rb @@ -1,5 +1,5 @@ class Person include ActiveModel::Validations - attr_accessor :title + attr_accessor :title, :karma end diff --git a/activemodel/test/schema.rb b/activemodel/test/schema.rb index f7fe31dc4e..56b824d445 100644 --- a/activemodel/test/schema.rb +++ b/activemodel/test/schema.rb @@ -1,13 +1,14 @@ ActiveRecord::Schema.define do create_table :topics, :force => true do |t| - t.string :title - t.string :author_name - t.text :content - t.boolean :approved, :default => true - t.string :type + t.string :title + t.string :author_name + t.text :content + t.boolean :approved, :default => true + t.string :type end create_table :developers, :force => true do |t| - t.string :name + t.string :name + t.float :salary end end -- cgit v1.2.3 From 320933205e16164ff55245aef1e95fb06e609d06 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sat, 21 Mar 2009 18:29:15 +0000 Subject: Deprecate Errors#on_base/add_to_base/invalid?/each_full --- .../validations/conditional_validation_test.rb | 6 +++--- activemodel/test/cases/validations_test.rb | 24 ++++++++++++++++------ 2 files changed, 21 insertions(+), 9 deletions(-) (limited to 'activemodel/test') diff --git a/activemodel/test/cases/validations/conditional_validation_test.rb b/activemodel/test/cases/validations/conditional_validation_test.rb index 72b4800dce..4c716d5d48 100644 --- a/activemodel/test/cases/validations/conditional_validation_test.rb +++ b/activemodel/test/cases/validations/conditional_validation_test.rb @@ -124,15 +124,15 @@ class ConditionalValidationTest < ActiveModel::TestCase Topic.validates_presence_of(:author_name, :if => "title.to_s.match('important')") t = Topic.new - assert !t.valid?, "A topic without a title should not be valid" - assert !t.errors.invalid?("author_name"), "A topic without an 'important' title should not require an author" + assert t.invalid?, "A topic without a title should not be valid" + assert t.errors[:author_name].empty?, "A topic without an 'important' title should not require an author" t.title = "Just a title" assert t.valid?, "A topic with a basic title should be valid" t.title = "A very important title" assert !t.valid?, "A topic with an important title, but without an author, should not be valid" - assert t.errors.invalid?("author_name"), "A topic with an 'important' title should require an author" + assert t.errors[:author_name].any?, "A topic with an 'important' title should require an author" t.author_name = "Hubert J. Farnsworth" assert t.valid?, "A topic with an important title and author should be valid" diff --git a/activemodel/test/cases/validations_test.rb b/activemodel/test/cases/validations_test.rb index a5dd7af04d..8c89494247 100644 --- a/activemodel/test/cases/validations_test.rb +++ b/activemodel/test/cases/validations_test.rb @@ -27,7 +27,7 @@ class ValidationsTest < ActiveModel::TestCase r = Reply.new r.title = "There's no content!" assert !r.valid? - assert r.errors.invalid?("content"), "A reply without content should mark that attribute as invalid" + assert r.errors[:content].any?, "A reply without content should mark that attribute as invalid" assert_equal ["Empty"], r.errors["content"], "A reply without content should contain an error" assert_equal 1, r.errors.count end @@ -36,10 +36,10 @@ class ValidationsTest < ActiveModel::TestCase r = Reply.new assert !r.valid? - assert r.errors.invalid?("title"), "A reply without title should mark that attribute as invalid" + assert r.errors[:title].any?, "A reply without title should mark that attribute as invalid" assert_equal ["Empty"], r.errors["title"], "A reply without title should contain an error" - assert r.errors.invalid?("content"), "A reply without content should mark that attribute as invalid" + assert r.errors[:content].any?, "A reply without content should mark that attribute as invalid" assert_equal ["Empty"], r.errors["content"], "A reply without content should contain an error" assert_equal 2, r.errors.count @@ -73,10 +73,10 @@ class ValidationsTest < ActiveModel::TestCase r = Reply.new r.content = "Mismatch" r.save - r.errors.add_to_base "Reply is not dignifying" + r.errors[:base] << "Reply is not dignifying" errors = [] - r.errors.each_full { |error| errors << error } + r.errors.to_a.each { |error| errors << error } assert_equal ["Reply is not dignifying"], r.errors[:base] @@ -134,7 +134,7 @@ class ValidationsTest < ActiveModel::TestCase t = Topic.new assert t.invalid? - assert t.errors.invalid?(:title) + assert t.errors[:title].any? t.title = 'Things are going to change' assert !t.invalid? @@ -163,4 +163,16 @@ class ValidationsTest < ActiveModel::TestCase end end end + + def test_deprecated_errors_on_base_and_each + t = Topic.new + assert t.valid? + + assert_deprecated { t.errors.add_to_base "invalid topic" } + assert_deprecated { assert_equal "invalid topic", t.errors.on_base } + assert_deprecated { assert t.errors.invalid?(:base) } + + all_errors = t.errors.to_a + assert_deprecated { assert_equal all_errors, t.errors.each_full{|err| err} } + end end \ No newline at end of file -- cgit v1.2.3 From d758d996d1b66e2a65640f79f01ce2ac674d7ed5 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sat, 21 Mar 2009 19:05:09 +0000 Subject: Deprecate Model#validate/validate_on_create/validate_on_update. Use Model.validate :method and likewise --- activemodel/test/models/reply.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'activemodel/test') diff --git a/activemodel/test/models/reply.rb b/activemodel/test/models/reply.rb index cfe256034c..acfd801674 100644 --- a/activemodel/test/models/reply.rb +++ b/activemodel/test/models/reply.rb @@ -4,9 +4,13 @@ class Reply < Topic validate :errors_on_empty_content validate_on_create :title_is_wrong_create + validate :check_empty_title + validate_on_create :check_content_mismatch + validate_on_update :check_wrong_update + attr_accessible :title, :author_name, :author_email_address, :written_on, :content, :last_read - def validate + def check_empty_title errors[:title] << "Empty" unless attribute_present?("title") end @@ -14,7 +18,7 @@ class Reply < Topic errors[:content] << "Empty" unless attribute_present?("content") end - def validate_on_create + def check_content_mismatch if attribute_present?("title") && attribute_present?("content") && content == "Mismatch" errors[:title] << "is Content Mismatch" end @@ -24,7 +28,7 @@ class Reply < Topic errors[:title] << "is Wrong Create" if attribute_present?("title") && title == "Wrong Create" end - def validate_on_update + def check_wrong_update errors[:title] << "is Wrong Update" if attribute_present?("title") && title == "Wrong Update" end end -- cgit v1.2.3