Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test records order in Rails?

I find very verbose and tedious to test if records coming from the database are correctly ordered. I'm thinking using the array '==' method to compare two searches arrays. The array's elements and order must be the same so it seems a good fit. The issue is that if elements are missing the test will fail even though they are strictly ordered properly.

I wonder if there is a better way...

like image 319
gamov Avatar asked Nov 11 '11 06:11

gamov


2 Answers

Rails 4

app/models/person.rb

default_scope { order(name: :asc) }


test/models/person.rb

test "people should be ordered by name" do
  xavier = Person.create(name: 'xavier')
  albert = Person.create(name: 'albert')
  all    = Person.all
  assert_operator all.index(albert), :<, all.index(xavier)
end

Rails 3

app/models/person.rb

default_scope order('name ASC')


test/unit/person_test.rb

test "people should be ordered by name" do 
  xavier = Person.create name: 'xavier'
  albert = Person.create name: 'albert'
  assert Person.all.index(albert) < Person.all.index(xavier)
end
like image 81
Damien Avatar answered Oct 21 '22 05:10

Damien


I haven't come across a built-in way to do this nicely but here's a way to check if an array of objects is sorted by a member:

class MyObject
  attr_reader :a

  def initialize(value)
    @a = value
  end
end

a = MyObject.new(2)
b = MyObject.new(3)
c = MyObject.new(4)

myobjects = [a, b, c]

class Array
  def sorted_by?(method)
    self.each_cons(2) do |a|
      return false if a[0].send(method) > a[1].send(method)
    end
    true
  end
end

p myobjects.sorted_by?(:a) #=> true

Then you can use it using something like:

test "people should be ordered by name by default" do 
  people = Person.all
  assert people.sorted_by?(:age)
end
like image 36
ramblex Avatar answered Oct 21 '22 06:10

ramblex