validates numericality only_integer fails to flag fractions as invalid (or RSpec test isn't correct) #9842

Closed
CraigAPayne opened this Issue Mar 20, 2013 · 2 comments

Projects

None yet

2 participants

@CraigAPayne

I'm using Rails 3.2.11, RSpec-rails 2.11.0, and Capybera 1.1.2. I can't get a validation test
to work as I expect. The test for 'only_integer' doesn't fail validation when a fraction is passed in.

NOTE - The migration has 'integer' as the type for 'rows' here... So, it could be there's some interaction there (the test trying to assign an Integer field a fraction), but that seems like a bug if that's what's happening - the test for validation should pass if the DB type is integer.

I've run the rake tasks db:reset, db:migrate, and db:test:prepare

[Stranger yet, if I add ", greater_than: 0" after only_integer: true - the test no longer fails]

The DB for my test environment is SQLite 3 (1.3.5). I'm running the tests with Spork and Guard.

My model code looks like:


class Storage < ActiveRecord::Base
attr_accessible :columns, :name, :rows
validates :name, presence: true
validates :rows, presence: true
validates_numericality_of :rows, only_integer: true
validates :columns, presence: true,
numericality: true
end


My RSpec looks like:

require 'spec_helper'

describe Storage do
before do
@storage = Storage.new
@storage.name = "Storage"
@storage.rows = 2
@storage.columns = 3
end

subject { @storage }

it { should be_valid }

it { should respond_to(:name) }
it { should respond_to(:rows) }
it { should respond_to(:columns) }

describe "with missing name" do
before { @storage.name = " " }
it { should_not be_valid }
end

describe "with missing row count" do
before { @storage.rows = " " }
it { should_not be_valid }
end

describe "with a non numberical row count" do
before { @storage.rows = "not a number" }
it { should_not be_valid }
end

describe "with a fractional row count" do
before { @storage.rows = 1/2 }
it { should_not be_valid } <<<<< FAILS HERE
end
end


The migration looks like:

class CreateStorages < ActiveRecord::Migration
def change
create_table :storages do |t|
t.string :name
t.integer :rows
t.integer :columns

  t.timestamps
end

end
end


The RSpec output is:

  1. Storage with a fractional row count
    Failure/Error: it { should_not be_valid }
    expected valid? to return false, got true

    ./spec/models/storage_spec.rb:37:in `block (3 levels) in <top (required)>'

So, I think this means that the problem is in the Rails validation code, not in RSpec.

@elektronaut

Looks like the error is in your test here:

before { @storage.rows = 1/2 } 

Ruby does integer division when you divide two integers:

>> 1/2
=> 0

Which is probably also why it passes when you add greater_than: 0

You can fix it by explicitely using floating point arithmetic:

before { @storage.rows = 1.0/2.0 } 
@CraigAPayne

That was it! Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment