validations_test.rb 7.5 KB
Newer Older
D
Initial  
David Heinemeier Hansson 已提交
1
require 'abstract_unit'
2 3 4
require 'fixtures/topic'
require 'fixtures/reply'
require 'fixtures/developer'
D
Initial  
David Heinemeier Hansson 已提交
5 6

class ValidationsTest < Test::Unit::TestCase
7
  fixtures :topics, :developers
D
Initial  
David Heinemeier Hansson 已提交
8

9 10 11 12 13
  def teardown
    Topic.write_inheritable_attribute("validate", [])
    Topic.write_inheritable_attribute("validate_on_create", [])
  end

D
Initial  
David Heinemeier Hansson 已提交
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
  def test_single_field_validation
    r = Reply.new
    r.title = "There's no content!"
    assert !r.save, "A reply without content shouldn't be saveable"

    r.content = "Messa content!"
    assert r.save, "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!"
    r.save
    assert r.errors.invalid?("content"), "A reply without content should mark that attribute as invalid"
    assert_equal "Empty", r.errors.on("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.save

    assert r.errors.invalid?("title"), "A reply without title should mark that attribute as invalid"
    assert_equal "Empty", r.errors.on("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.on("content"), "A reply without content should contain an error"

    assert_equal 2, r.errors.count
  end
  
  def test_error_on_create
    r = Reply.new
    r.title = "Wrong Create"
    assert !r.save
    assert r.errors.invalid?("title"), "A reply with a bad title should mark that attribute as invalid"
    assert_equal "is Wrong Create", r.errors.on("title"), "A reply with a bad content should contain an error"
  end

  
  def test_error_on_update
    r = Reply.new
    r.title = "Bad"
    r.content = "Good"

    assert r.save, "First save should be successful"
    
    r.title = "Wrong Update"
    assert !r.save, "Second save should fail"
    
    assert r.errors.invalid?("title"), "A reply with a bad title should mark that attribute as invalid"
    assert_equal "is Wrong Update", r.errors.on("title"), "A reply with a bad content should contain an error"
  end
  
  def test_single_error_per_attr_iteration
    r = Reply.new
    r.save
    
    errors = []
    r.errors.each { |attr, msg| errors << [attr, msg] }
    
    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.each_full { |error| errors << error }
    
    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_create_without_validation
    reply = Reply.new
    assert !reply.save
    assert reply.save(false)
  end
  
  def test_errors_on_boundary_breaking
    developer = Developer.new("name" => "xs")
    assert !developer.save
    assert_equal "is too short (min is 3 characters)", developer.errors.on("name")
    
    developer.name = "All too very long for this boundary, it really is"
    assert !developer.save
    assert_equal "is too long (max is 20 characters)", developer.errors.on("name")

    developer.name = "Just right"
    assert developer.save
  end
127

128
  def test_title_confirmation
129
    Topic.validates_confirmation_of(:title)
130

131 132
    t = Topic.create("title" => "We should be confirmed")
    assert !t.save
133

134 135
    t.title_confirmation = "We should be confirmed"
    assert t.save
136 137
  end

138
  def test_terms_of_service_agreement
139
    Topic.validates_acceptance_of(:terms_of_service, :on => :create)
140

141 142
    t = Topic.create("title" => "We should be confirmed")
    assert !t.save
143
    assert_equal "must be accepted", t.errors.on(:terms_of_service)
144

145
    t.terms_of_service = "1"
146 147
    assert t.save
  end
148 149 150


  def test_eula
151
    Topic.validates_acceptance_of(:eula, :message => "must be abided", :on => :create)
152 153 154 155 156 157 158

    t = Topic.create("title" => "We should be confirmed")
    assert !t.save
    assert_equal "must be abided", t.errors.on(:eula)

    t.eula = "1"
    assert t.save
159 160 161
  end
  
  def test_validate_presences
162
    Topic.validates_presence_of(:title, :content)
163

164 165 166 167 168 169 170 171 172
    t = Topic.create
    assert !t.save
    assert_equal "can't be empty", t.errors.on(:title)
    assert_equal "can't be empty", t.errors.on(:content)
    
    t.title = "something"
    t.content  = "another"
    
    assert t.save
173
  end
174 175
  
  def test_validate_uniqueness
176
    Topic.validates_uniqueness_of(:title)
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
    
    t = Topic.new("title" => "I'm unique!")
    assert t.save, "Should save t as unique"

    t.content = "Remaining unique"
    assert t.save, "Should still save t as unique"

    t2 = Topic.new("title" => "I'm unique!")
    assert !t2.valid?, "Shouldn't be valid"
    assert !t2.save, "Shouldn't save t2 as unique"
    assert_equal "has already been taken", t2.errors.on(:title)
    
    t2.title = "Now Im really also unique"
    assert t2.save, "Should now save t2 as unique"
  end
192 193
  
  def test_validate_boundaries
194
    Topic.validates_boundaries_of(:title, :content, :within => 3..5)
195 196 197 198 199 200 201 202 203 204 205

    t = Topic.create("title" => "a!", "content" => "I'm ooooooooh so very long")
    assert !t.save
    assert_equal "is too short (min is 3 characters)", t.errors.on(:title)
    assert_equal "is too long (max is 5 characters)", t.errors.on(:content)

    t.title = "abe"
    t.content  = "mad"

    assert t.save
  end
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222

  def test_validate_format
    Topic.validates_format_of(:title, :content, :with => /^Validation macros rule!$/, :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.on(:title)
    assert_nil t.errors.on(:content)

    t.title = "Validation macros rule!"

    assert t.save
    assert_nil t.errors.on(:title)

    assert_raise(ArgumentError) { Topic.validates_format_of(:title, :content) }
  end
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245

  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?
    assert !Topic.create("title" => %w(a b c), "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["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
246
end