Skip to content

Instantly share code, notes, and snippets.

@ubermajestix
Created September 5, 2012 20:35

Revisions

  1. ubermajestix created this gist Sep 5, 2012.
    63 changes: 63 additions & 0 deletions inspector.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,63 @@
    # When an RSpec test like this fails,
    #
    # @my_array.should == [@some_model, @some_model2]
    #
    # RSpec will call inspect on each of the objects to "help" you figure out
    # what went wrong. Well, inspect will usually dump a TON OF SHIT and make trying
    # to figure out why `@my_array` is not made up of `@some_model` and `@some_model2`.
    #
    # This little module and technique helps get around that. It will redefine `inspect`
    # if you include it in your model object.
    #
    # You can define a whitelist of methods that inspect will dump.
    # It will always provide `object_id` at a minimum.
    #
    # To use it, drop it in spec/support/inspector.rb and class_eval the models to
    # override `inspect`.
    module Inspector

    def inspect
    string = "#<#{self.class.name}:#{self.object_id} "
    fields = self.class.inspector_fields.map{|field| "#{field}: #{self.send(field)}"}
    string << fields.join(", ") << ">"
    end

    def self.inspected
    @inspected ||= []
    end

    def self.included source
    # $stdout.puts "Overriding inspect on #{source}"
    inspected << source
    source.class_eval do
    def self.inspector *fields
    @inspector_fields = *fields
    end

    def self.inspector_fields
    @inspector_fields ||= []
    end
    end
    end
    end

    # Examples

    # For use when testing you can class eval the model you want
    # to override the inspect behavior on.
    User.class_eval do
    include Inspector
    inspector :id, :email, :company_id
    end

    # There's also nothing stopping you from doing this in
    # any ruby class
    class User
    # ...
    include Inspector
    inspector :id, :email, :company_id
    #...
    end

    puts User.new.inspect
    # => #<User:0x10c7a2f80 id: 1, email: "tyler@example.com", company_id: 1>