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

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

    t.title = nil
    assert !t.valid?
51
    assert t.errors[:title].any?
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
    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?
73 74
    assert t.errors[:title].any?
    assert_equal ["is too long (maximum is 5 characters)"], t.errors[:title]
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97

    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?
98 99
    assert_equal ["is too short (minimum is 3 characters)"], t.errors[:title]
    assert_equal ["is too long (maximum is 5 characters)"], t.errors[:content]
100 101 102 103

    t.title = nil
    t.content = nil
    assert !t.valid?
104 105
    assert_equal ["is too short (minimum is 3 characters)"], t.errors[:title]
    assert_equal ["is too short (minimum is 3 characters)"], t.errors[:content]
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126

    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
127 128
    assert t.errors[:title].any?
    assert_equal ["my string is too long: 10"], t.errors[:title]
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147

    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
148
    assert t.errors[:title].any?
149 150 151

    t.title = "not"
    assert !t.save
152 153
    assert t.errors[:title].any?
    assert_equal ["my string is too short: 5"], t.errors[:title]
154 155 156 157

    t.title = "valid"
    t.content = "andthisistoolong"
    assert !t.save
158
    assert t.errors[:content].any?
159 160 161 162 163 164 165 166 167 168 169 170 171

    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?
172 173
    assert t.errors[:title].any?
    assert_equal ["is the wrong length (should be 5 characters)"], t.errors[:title]
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 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

    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
    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?
220 221
    assert t.errors[:title].any?
    assert_equal ["boo 5"], t.errors[:title]
222 223 224 225 226 227
  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?
228 229
    assert t.errors[:title].any?
    assert_equal ["hoo 5"], t.errors[:title]
230 231 232 233 234 235
  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?
236
    assert t.errors[:title].any?
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 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 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367
    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?
368
      assert_equal ["短すぎます: 5"], t.errors[:title]
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 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 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433

      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
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448

  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
449
end