length_validation_test.rb 13.3 KB
Newer Older
1 2
# encoding: utf-8
require 'cases/helper'
P
Pratik Naik 已提交
3
require 'cases/tests_database'
4 5

require 'models/topic'
6 7
require 'models/developer'
require 'models/person'
8 9

class LengthValidationTest < ActiveModel::TestCase
P
Pratik Naik 已提交
10
  include ActiveModel::TestsDatabase
11

12 13 14
  def teardown
    Topic.reset_callbacks(:validate)
  end
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

  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?
42 43
    assert t.errors[:title].any?
    assert_equal ["is too short (minimum is 5 characters)"], t.errors[:title]
44 45 46

    t.title = ""
    assert !t.valid?
47 48
    assert t.errors[:title].any?
    assert_equal ["is too short (minimum is 5 characters)"], t.errors[:title]
49 50 51

    t.title = nil
    assert !t.valid?
52
    assert t.errors[:title].any?
53 54 55
    assert_equal ["is too short (minimum is 5 characters)"], t.errors["title"]
  end

56 57 58 59 60 61
  def test_validates_length_of_using_maximum_should_allow_nil
    Topic.validates_length_of :title, :maximum => 10
    t = Topic.create
    assert t.valid?
  end

62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
  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?
80 81
    assert t.errors[:title].any?
    assert_equal ["is too long (maximum is 5 characters)"], t.errors[:title]
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

    t.title = ""
    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?
102 103
    assert_equal ["is too short (minimum is 3 characters)"], t.errors[:title]
    assert_equal ["is too long (maximum is 5 characters)"], t.errors[:content]
104 105 106 107

    t.title = nil
    t.content = nil
    assert !t.valid?
108 109
    assert_equal ["is too short (minimum is 3 characters)"], t.errors[:title]
    assert_equal ["is too short (minimum is 3 characters)"], t.errors[:content]
110 111 112 113 114 115

    t.title = "abe"
    t.content  = "mad"
    assert t.valid?
  end

116 117 118 119 120 121 122 123 124 125 126 127 128 129
  def test_validates_length_of_using_within_with_exclusive_range
    Topic.validates_length_of(:title, :within => 4...10)

    t = Topic.new("title" => "9 chars!!")
    assert t.valid?

    t.title = "Now I'm 10"
    assert !t.valid?
    assert_equal ["is too long (maximum is 9 characters)"], t.errors[:title]

    t.title = "Four"
    assert t.valid?
  end

130 131 132 133 134 135 136 137 138 139 140
  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
141
    Topic.validates_length_of :title, :content, :within => 5..10, :on => :create, :too_long => "my string is too long: %{count}"
142 143 144

    t = Topic.create("title" => "thisisnotvalid", "content" => "whatever")
    assert !t.save
145 146
    assert t.errors[:title].any?
    assert_equal ["my string is too long: 10"], t.errors[:title]
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161

    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
162
    Topic.validates_length_of :title, :content, :within => 5..10, :on => :update, :too_short => "my string is too short: %{count}"
163 164 165

    t = Topic.create("title" => "vali", "content" => "whatever")
    assert !t.save
166
    assert t.errors[:title].any?
167 168 169

    t.title = "not"
    assert !t.save
170 171
    assert t.errors[:title].any?
    assert_equal ["my string is too short: 5"], t.errors[:title]
172 173 174 175

    t.title = "valid"
    t.content = "andthisistoolong"
    assert !t.save
176
    assert t.errors[:content].any?
177 178 179 180 181 182 183 184 185 186 187 188 189

    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?
190 191
    assert t.errors[:title].any?
    assert_equal ["is the wrong length (should be 5 characters)"], t.errors[:title]
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223

    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_of_nasty_params
224 225
    assert_raise(ArgumentError) { Topic.validates_length_of(:title, :is=>-6) }
    assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within=>6) }
226 227 228 229 230 231 232
    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
233
    Topic.validates_length_of( :title, :minimum=>5, :message=>"boo %{count}" )
234 235
    t = Topic.create("title" => "uhoh", "content" => "whatever")
    assert !t.valid?
236 237
    assert t.errors[:title].any?
    assert_equal ["boo 5"], t.errors[:title]
238 239 240
  end

  def test_validates_length_of_custom_errors_for_minimum_with_too_short
241
    Topic.validates_length_of( :title, :minimum=>5, :too_short=>"hoo %{count}" )
242 243
    t = Topic.create("title" => "uhoh", "content" => "whatever")
    assert !t.valid?
244 245
    assert t.errors[:title].any?
    assert_equal ["hoo 5"], t.errors[:title]
246 247 248
  end

  def test_validates_length_of_custom_errors_for_maximum_with_message
249
    Topic.validates_length_of( :title, :maximum=>5, :message=>"boo %{count}" )
250 251
    t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
    assert !t.valid?
252
    assert t.errors[:title].any?
253 254 255 256
    assert_equal ["boo 5"], t.errors[:title]
  end

  def test_validates_length_of_custom_errors_for_in
257
    Topic.validates_length_of(:title, :in => 10..20, :message => "hoo %{count}")
258 259 260 261 262 263 264 265 266 267 268 269
    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
270
    Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}" )
271 272 273 274 275 276 277
    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
278
    Topic.validates_length_of( :title, :is=>5, :message=>"boo %{count}" )
279 280 281 282 283 284 285
    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
286
    Topic.validates_length_of( :title, :is=>5, :wrong_length=>"hoo %{count}" )
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
    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
352
      Topic.validates_length_of :title, :within => 5..10, :on => :create, :too_long => "長すぎます: %{count}"
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374

      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
375
      Topic.validates_length_of :title, :within => 5..10, :on => :update, :too_short => "短すぎます: %{count}"
376 377 378 379 380 381 382 383

      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?
384
      assert_equal ["短すぎます: 5"], t.errors[:title]
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409

      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
410
    Topic.validates_length_of :content, :minimum => 5, :too_short=>"Your essay must be at least %{count} words.",
411 412 413 414 415 416 417 418 419 420
                                        :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

421
  def test_validates_length_of_for_ruby_class
422
    Person.validates_length_of :karma, :minimum => 5
423

424 425 426
    p = Person.new
    p.karma = "Pix"
    assert p.invalid?
427

428
    assert_equal ["is too short (minimum is 5 characters)"], p.errors[:karma]
429

430 431 432 433
    p.karma = "The Smiths"
    assert p.valid?
  ensure
    Person.reset_callbacks(:validate)
434
  end
435
end