diff --git a/README.md b/README.md index e63f8459..0850399e 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,13 @@ Default options: :index => true, # Display array indices. :html => false, # Use ANSI color codes rather than HTML. :sorted_hash_keys => false, # Do not sort hash keys. + :mongo_mapper => { + :show_associations => false, # Display association data for MongoMapper documents and classes + :inline_embedded => false # Display embedded associations inline with MongoMapper documents + }, :color => { :array => :white, + :assoc => :greenish, :bignum => :blue, :class => :yellow, :date => :greenish, diff --git a/lib/ap/awesome_print.rb b/lib/ap/awesome_print.rb index 1fa98319..b7106aa0 100755 --- a/lib/ap/awesome_print.rb +++ b/lib/ap/awesome_print.rb @@ -19,8 +19,13 @@ def initialize(options = {}) :index => true, # Display array indices. :html => false, # Use ANSI color codes rather than HTML. :sorted_hash_keys => false, # Do not sort hash keys. + :mongo_mapper => { + :show_associations => false, # Display association data for MongoMapper documents and classes + :inline_embedded => false # Display embedded associations inline with MongoMapper documents + }, :color => { :array => :white, + :assoc => :greenish, :bigdecimal => :blue, :class => :yellow, :date => :greenish, @@ -307,9 +312,10 @@ def outdent @outdent = ' ' * (@indentation - @options[:indent].abs) end - # Update @options by first merging the :color hash and then the remaining keys. + # Update @options by first merging the :mongo_mapper and :color hash and then the remaining keys. #------------------------------------------------------------------------------ def merge_options!(options = {}) + @options[:mongo_mapper].merge!(options.delete(:mongo_mapper) || {}) @options[:color].merge!(options.delete(:color) || {}) @options.merge!(options) end diff --git a/lib/ap/mixin/mongo_mapper.rb b/lib/ap/mixin/mongo_mapper.rb index 5e8e07ab..d757ae33 100644 --- a/lib/ap/mixin/mongo_mapper.rb +++ b/lib/ap/mixin/mongo_mapper.rb @@ -19,6 +19,8 @@ def printable_with_mongo_mapper(object) if printable == :self if object.is_a?(MongoMapper::Document) || object.is_a?(MongoMapper::EmbeddedDocument) printable = :mongo_mapper_instance + elsif object.is_a?(MongoMapper::Plugins::Associations::Base) + printable = :mongo_mapper_association end elsif printable == :class && (object.ancestors & [MongoMapper::Document, MongoMapper::EmbeddedDocument]).size > 0 printable = :mongo_mapper_class @@ -35,7 +37,34 @@ def awesome_mongo_mapper_instance(object) hash[name] = object[name] hash end - "#{object} " + awesome_hash(data) + + # Add in associations + if @options[:mongo_mapper][:show_associations] + object.associations.each do |name, assoc| + if @options[:mongo_mapper][:inline_embedded] and assoc.embeddable? + data[name.to_s] = object.send(name) + else + data[name.to_s] = assoc + end + end + end + + label = object.to_s + label = "#{colorize('embedded', :assoc)} #{label}" if object.is_a?(MongoMapper::EmbeddedDocument) + + "#{label} #{awesome_hash(data)}" + end + + # Format MongoMapper association object. + #------------------------------------------------------------------------------ + def awesome_mongo_mapper_association(object) + return object.inspect if !defined?(ActiveSupport::OrderedHash) + + association = object.class.name.split('::').last.titleize.downcase.sub(/ association$/,'') + association = "embeds #{association}" if object.embeddable? + class_name = object.class_name + + "#{colorize(association, :assoc)} #{colorize(class_name, :class)}" end # Format MongoMapper class object. @@ -47,6 +76,14 @@ def awesome_mongo_mapper_class(object) hash[c.first] = (c.last.type || "undefined").to_s.underscore.intern hash end + + # Add in associations + if @options[:mongo_mapper][:show_associations] + object.associations.each do |name, assoc| + data[name.to_s] = assoc + end + end + "class #{object} < #{object.superclass} " << awesome_hash(data) end end diff --git a/spec/methods_spec.rb b/spec/methods_spec.rb index 7ce206b9..3670c476 100644 --- a/spec/methods_spec.rb +++ b/spec/methods_spec.rb @@ -118,6 +118,10 @@ def world(a,b); end end describe "object.protected_methods" do + before do + stub_dotfile! + end + it "index: should handle object.protected_methods" do class Hello protected @@ -354,6 +358,7 @@ def m1(a, b = nil, &blk); end # m1(a, *b, &blk) end it "obj1.methods - obj2.methods should be awesome printed" do + stub_dotfile! class Hello def self.m1; end end @@ -362,6 +367,7 @@ def self.m1; end end it "obj1.methods & obj2.methods should be awesome printed" do + stub_dotfile! class Hello def self.m1; end def self.m2; end @@ -374,6 +380,7 @@ def self.m1; end end it "obj1.methods.grep(pattern) should be awesome printed" do + stub_dotfile! class Hello def self.m1; end def self.m2; end @@ -396,6 +403,7 @@ def self.m_two; end end it "obj1.methods.grep(pattern, &block) should be awesome printed" do + stub_dotfile! class Hello def self.m0; end def self.none; end diff --git a/spec/mongo_mapper_spec.rb b/spec/mongo_mapper_spec.rb index 1bc6d4da..345254a2 100644 --- a/spec/mongo_mapper_spec.rb +++ b/spec/mongo_mapper_spec.rb @@ -15,6 +15,7 @@ class MongoUser end before :each do + stub_dotfile! @ap = AwesomePrint.new(:plain => true) end @@ -56,6 +57,116 @@ class Chamelion < Object { } EOS end + + context "with associations" do + before :all do + class Child + include MongoMapper::EmbeddedDocument + key :data + end + + class Sibling + include MongoMapper::Document + key :title + end + + class Parent + include MongoMapper::Document + key :name + + one :child + one :sibling + end + end + + context "with show associations turned off (default)" do + it "should render the class as normal" do + @ap.send(:awesome, Parent).should == <<-EOS.strip +class Parent < Object { + "_id" => :object_id, + "name" => :undefined +} +EOS + end + + it "should render an instance as normal" do + parent = Parent.new(:name => 'test') + out = @ap.send(:awesome, parent) + str = <<-EOS.strip +# { + "_id" => BSON::ObjectId('4d9183739a546f6806000001'), + "name" => "test" +} +EOS + out.gsub!(/'([\w]+){23}'/, "'4d9183739a546f6806000001'") + out.gsub!(/0x([a-f\d]+)/, "0x01234567") + out.should == str + end + end + + context "with show associations turned on and inline embedded turned off" do + before :each do + @ap = AwesomePrint.new(:plain => true, + :mongo_mapper => { + :show_associations => true }) + end + + it "should render the class with associations shown" do + @ap.send(:awesome, Parent).should == <<-EOS.strip +class Parent < Object { + "_id" => :object_id, + "name" => :undefined, + "child" => embeds one Child, + "sibling" => one Sibling +} +EOS + end + + it "should render an instance with associations shown" do + parent = Parent.new(:name => 'test') + out = @ap.send(:awesome, parent) + str = <<-EOS.strip +# { + "_id" => BSON::ObjectId('4d9183739a546f6806000001'), + "name" => "test", + "child" => embeds one Child, + "sibling" => one Sibling +} +EOS + out.gsub!(/'([\w]+){23}'/, "'4d9183739a546f6806000001'") + out.gsub!(/0x([a-f\d]+)/, "0x01234567") + out.should == str + end + end + + context "with show associations turned on and inline embedded turned on" do + before :each do + @ap = AwesomePrint.new(:plain => true, + :mongo_mapper => { + :show_associations => true, + :inline_embedded => true }) + end + + it "should render an instance with associations shown and embeds there" do + parent = Parent.new(:name => 'test', :child => Child.new(:data => 5)) + out = @ap.send(:awesome, parent) + str = <<-EOS.strip +# { + "_id" => BSON::ObjectId('4d9183739a546f6806000001'), + "name" => "test", + "child" => embedded # { + "_id" => BSON::ObjectId('4d9183739a546f6806000001'), + "data" => 5 + }, + "sibling" => one Sibling +} +EOS + out.gsub!(/'([\w]+){23}'/, "'4d9183739a546f6806000001'") + out.gsub!(/0x([a-f\d]+)/, "0x01234567") + out.should == str + end + end + end end rescue LoadError