A sorted_by custom matcher for RSpec

I recently had to test that the result of an Active Record query was sorted by a particular attribute of the model. In this case, the model implemented the acts_as_list mixin and the result set had to be sorted by the position attribute. I came up with the following RSpec custom matcher.:

RSpec::Matchers.define :be_sorted_by do |attr|
  match do |records|
    a = records.map{ |record| record.send(attr) }
    a.sort == a
  end
end

One limitation of this solution is that it only works for ascending order but it can be extended by supplying an extra argument for the direction.

It can then be used in an RSpec example as follows:

subject { ... }
it "should be sorted" do
  should be_sorted_by(:position)
end
Write us your thoughts about this post. Be kind & Play nice.