Skip to content

Instantly share code, notes, and snippets.

@stuliston
Last active December 27, 2015 20:39
Show Gist options
  • Save stuliston/7385641 to your computer and use it in GitHub Desktop.
Save stuliston/7385641 to your computer and use it in GitHub Desktop.
IN YOUR ActiveRecord::Face
# DISCLAIMER: Beer was consumed
# Need to make assertions about ActiveRecord query messages applied to
# a model but don't want to include AR as a dependency? Feeling yolo?
# I had that situation lately with a gem that takes params and uses macros
# to build a scoped relation (github.com/hooroo/query_ar), so I cooked this up.
# Usage is as follows.
# Declare a class that inherits us instead of AR::Base
#
# class User < ActiveRecord::Face
# scope :active
# end
# Chain a bunch of query methods together
#
# > User.active.where(name: 'stu').order('name').limit(10).offset(0)
# Find out what messages where received and with what args, useful for assertions
#
# > User.messages_received
# => {:active=>[], :where=>[{:name=>"stu"}], :order=>["name"], :limit=>[10], :offset=>[0]}
require 'active_support/core_ext'
module ActiveRecord
class Face
class_attribute :messages_received, :expected_messages
self.expected_messages = Set.new([
:all,
:where,
:order,
:limit,
:offset,
:includes
])
def self.scope(name)
self.expected_messages << name.to_sym
end
def self.method_missing(method, *args, &block)
super unless self.expected_messages.include?(method)
self.messages_received ||= {}
self.messages_received.merge!(method => args)
self
end
end
end
require 'support/active_record/face'
class FakeModel < ActiveRecord::Face
scope :active
end
describe ActiveRecord::Face do
it "keeps track of class messages received" do
FakeModel.active.where(name: 'stu').order('name').limit(10).offset(0)
messages = FakeModel.messages_received
expect(messages.keys.length).to eq 5
expect(messages).to include(active: [])
expect(messages).to include(where: [{name: 'stu'}])
expect(messages).to include(order: ['name'])
expect(messages).to include(limit: [10])
expect(messages).to include(offset: [0])
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment