[DRE-commits] [ruby-awesome-print] 01/04: Imported Upstream version 1.2.0

Tim Potter tpot-guest at moszumanska.debian.org
Wed Jul 30 01:08:26 UTC 2014


This is an automated email from the git hooks/post-receive script.

tpot-guest pushed a commit to branch master
in repository ruby-awesome-print.

commit de8b7327a18783b4a482f1dc8ca247f3740db941
Author: Tim Potter <tpot at hp.com>
Date:   Fri Jul 25 12:11:01 2014 +1000

    Imported Upstream version 1.2.0
---
 .gitignore                              |  24 ++
 CHANGELOG                               |  96 +++++
 Gemfile                                 |   3 +
 Gemfile.lock                            |  26 ++
 LICENSE                                 |  22 +
 README.md                               | 366 ++++++++++++++++
 Rakefile                                |  11 +
 lib/ap.rb                               |  10 +
 lib/awesome_print.rb                    |  35 ++
 lib/awesome_print/core_ext/array.rb     |  81 ++++
 lib/awesome_print/core_ext/class.rb     |  22 +
 lib/awesome_print/core_ext/kernel.rb    |  26 ++
 lib/awesome_print/core_ext/logger.rb    |  20 +
 lib/awesome_print/core_ext/method.rb    |  21 +
 lib/awesome_print/core_ext/object.rb    |  22 +
 lib/awesome_print/core_ext/string.rb    |  31 ++
 lib/awesome_print/ext/action_view.rb    |  18 +
 lib/awesome_print/ext/active_record.rb  |  69 ++++
 lib/awesome_print/ext/active_support.rb |  47 +++
 lib/awesome_print/ext/mongo_mapper.rb   | 121 ++++++
 lib/awesome_print/ext/mongoid.rb        |  65 +++
 lib/awesome_print/ext/no_brainer.rb     |  58 +++
 lib/awesome_print/ext/nokogiri.rb       |  45 ++
 lib/awesome_print/ext/ripple.rb         |  72 ++++
 lib/awesome_print/ext/sequel.rb         |  57 +++
 lib/awesome_print/formatter.rb          | 407 ++++++++++++++++++
 lib/awesome_print/inspector.rb          | 171 ++++++++
 lib/awesome_print/version.rb            |  10 +
 metadata.yml                            | 117 ++++++
 spec/colors_spec.rb                     | 106 +++++
 spec/formats_spec.rb                    | 712 ++++++++++++++++++++++++++++++++
 spec/methods_spec.rb                    | 459 ++++++++++++++++++++
 spec/misc_spec.rb                       | 229 ++++++++++
 spec/objects_spec.rb                    |  85 ++++
 spec/spec_helper.rb                     |  64 +++
 35 files changed, 3728 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..14f43a2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,24 @@
+## MAC OS
+.DS_Store
+
+## TEXTMATE
+*.tmproj
+tmtags
+
+## EMACS
+*~
+\#*
+.\#*
+
+## VIM
+*.swp
+
+## PROJECT::GENERAL
+coverage
+rdoc
+pkg
+Gemfile.lock
+
+## PROJECT::SPECIFIC
+.rvmrc
+.idea
diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644
index 0000000..f84e868
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,96 @@
+1.2.0 <-- NOTE: This is the *last* release supporting Ruby < v1.9.3 and Rails < v3.
+  - Added Sequel ORM plugin (Jonathan Davies)
+  - Added Ripple plugin (Ruby modeling layer for Riak, Scott Hyndman)
+  - Added NoBrainer plugin (Ruby ORM for RethinkDB, Nicolas Viennot)
+  - Added formatting for Ruby set objects (Richard Hall)
+  - Fixed HTML formatting (Mike McQuaid)
+  - Other minor bugs and enhancements
+
+1.1.0
+  - Objects are no longer recursively formatted by default. Reenable by using :raw => true option.
+  - ap(object) now returns nil when running under IRB or Pry
+  - Added support for Mongoid 3 and Moped (Nikolaj Nikolajsen)
+  - Improved formatting of MongoMapper objects (George .)
+  - ActiveRecord::Relation now renders as array (Dan Lynn)
+  - Formatting BigDecimal no longer looses precision (Evan Senter)
+  - Added AwesomePrint.irb! and AwesomePrint.pry! convenience methods
+  - Fixed conflict with the colorize gem
+  - Misc tweaks and bug fixes
+
+1.0.2
+  - Added formatting of Mongoid documents (Adam Doppelt)
+  - ActiveRecord objects display attributes only. Use :raw => true to display the entire object
+  - ActiveSupport::Date objects get formatted as regular Date
+  - Rails.logger.ap colorizes output based on ActiveSupport::LogSubscriber.colorize_logging (default is true)
+  - Improved formatting of methods array
+
+1.0.1
+  - Updated repo tags for Rubygems.org
+
+1.0.0 Thanksgiving edition
+  - Added ability to format *arbitrary* Ruby object
+  - Added :limit option to limit large output for arrays and hashes (Andrew Horsman)
+  - Improved HTML formatting when :html => true (Daniel Johnson)
+  - Added Mongoid extension (Adam Doppelt)
+  - Added Nokogiri extension (Adam Doppelt)
+  - Removed Jeweler gem dependency
+
+0.4.0
+  - 'ap object' now returns the object (Stephan Hagemann)
+  - Added :html => true option to enable HTML colors rather that ANSI (ex. Sinatra templates)
+  - Added AwesomePrint.force_colors! to allow color output on demand (Andrew O'Brien)
+  - Added MongoMapper formatter mixin (Elpizo Choi)
+  - Fixed formatting of methods array when object#method is overridden
+  - Fixed potential stack errors by checking whether AwesomePrint is already loaded
+  - Improved Ruby 1.8.6 and 1.8.7 compatibility
+  - Improved Windows compatibility (Viktar Basharymau)
+
+0.3.2
+  - Make sure Rails mixins get loaded in Rails console when required from .irbrc
+  - Fixed an issue with classes that define their own #send method (ex: Socket)
+  - Fixed compatibility issue with Liquid gem that defines Module#liquid_methods
+  - Fixed hash spec for Ruby < 1.9 where order of hash keys is not guaranteed
+  - Added :sorted_hash_keys option to sort hash keys (Ed Ruder)
+
+0.3.1 RubyConf X edition
+  - Fixed Ruby 1.8.6 compatibility issues (thanks, Tim!)
+  - Fixed stack overflow issue with Rails 2.3.x console
+
+0.3.0
+  - Display object.methods and family in human readable format
+  - Objects inherited from Array, Hash, File, Dir, and Struct are shown as their base class
+  - Added option to suppress array index in output (Sean Gallagher)
+  - Updated README on how to set up ~/.irbrc for MacRuby (Eloy Duran)
+  - Specs pass 100% with Ruby 1.8.7/RSpec 1.3 and Ruby 1.9.2/RSpec 2.0
+
+0.2.1
+  - ap can now be used within Rails templates (ex. <%= ap object %>)
+  - Added support for printing Struct
+
+0.2.0
+  - Added support for logger.ap (including Rails logger)
+  - Added support for HashWithIndifferentAccess from ActiveSupport
+  - ap now works with scripts that use ActiveRecord/ActiveSupport outside Rails
+  - ap now correctly shows file and directory names with fancy characters (shell escape)
+
+0.1.4
+  - Format BigDecimal and Rational objects as Float scalars
+  - Explicit options parameter can override custom defaults
+  - Custom defaults are not interfering when running specs
+  - Custom defaults now work correctly with Ruby 1.9.x
+
+0.1.3
+  - Added support for setting custom defaults in ~/.aprc
+  
+0.1.2
+  - Correctly handle empty arrays and hashes
+  - Use alias_method instead of alias (fixes non-tty method aliasing)
+  - Added awesome_inspect method
+
+0.1.1
+  - Added support for tableless ActiveRecord models
+  - Left align hash keys if @options[:indent] is negative
+  
+0.1.0
+  - Initial Release.
+  
\ No newline at end of file
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..b47bb79
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,3 @@
+source "https://rubygems.org"
+gemspec
+
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 0000000..285fa51
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,26 @@
+PATH
+  remote: .
+  specs:
+    awesome_print (1.1.0)
+
+GEM
+  remote: https://rubygems.org/
+  specs:
+    diff-lcs (1.1.3)
+    fakefs (0.3.2)
+    rspec (2.11.0)
+      rspec-core (~> 2.11.0)
+      rspec-expectations (~> 2.11.0)
+      rspec-mocks (~> 2.11.0)
+    rspec-core (2.11.1)
+    rspec-expectations (2.11.2)
+      diff-lcs (~> 1.1.3)
+    rspec-mocks (2.11.2)
+
+PLATFORMS
+  ruby
+
+DEPENDENCIES
+  awesome_print!
+  fakefs (>= 0.2.1)
+  rspec (>= 2.6.0)
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..c835968
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2010-2013 Michael Dvorkin
+http://www.dvorkin.net
+%w(mike dvorkin.net) * "@" || %w(mike fatfreecrm.com) * "@"
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..689fafd
--- /dev/null
+++ b/README.md
@@ -0,0 +1,366 @@
+## Awesome Print ##
+Awesome Print is a Ruby library that pretty prints Ruby objects in full color
+exposing their internal structure with proper indentation. Rails ActiveRecord
+objects and usage within Rails templates are supported via included mixins.
+
+__NOTE__: awesome_print v1.2.0 is the last release supporting Ruby versions
+prior to v1.9.3 and Rails versions prior to v3.0. The upcoming awesome_print
+v2.0 will *require* Ruby v1.9.3 or later and Rails v3.0 or later.
+
+### Installation ###
+    # Installing as Ruby gem
+    $ gem install awesome_print
+
+    # Cloning the repository
+    $ git clone git://github.com/michaeldv/awesome_print.git
+
+### Usage ###
+
+```ruby
+require "awesome_print"
+ap object, options = {}
+```
+
+Default options:
+
+```ruby
+:indent     => 4,      # Indent using 4 spaces.
+:index      => true,   # Display array indices.
+:html       => false,  # Use ANSI color codes rather than HTML.
+:multiline  => true,   # Display in multiple lines.
+:plain      => false,  # Use colors.
+:raw        => false,  # Do not recursively format object instance variables.
+:sort_keys  => false,  # Do not sort hash keys.
+:limit      => false,  # Limit large output for arrays and hashes. Set to a boolean or integer.
+:color => {
+  :args       => :pale,
+  :array      => :white,
+  :bigdecimal => :blue,
+  :class      => :yellow,
+  :date       => :greenish,
+  :falseclass => :red,
+  :fixnum     => :blue,
+  :float      => :blue,
+  :hash       => :pale,
+  :keyword    => :cyan,
+  :method     => :purpleish,
+  :nilclass   => :red,
+  :rational   => :blue,
+  :string     => :yellowish,
+  :struct     => :pale,
+  :symbol     => :cyanish,
+  :time       => :greenish,
+  :trueclass  => :green,
+  :variable   => :cyanish
+}
+```
+
+Supported color names:
+
+```ruby
+:gray, :red, :green, :yellow, :blue, :purple, :cyan, :white
+:black, :redish, :greenish, :yellowish, :blueish, :purpleish, :cyanish, :pale
+```
+
+### Examples ###
+
+```ruby
+$ cat > 1.rb
+require "awesome_print"
+data = [ false, 42, %w(forty two), { :now => Time.now, :class => Time.now.class, :distance => 42e42 } ]
+ap data
+^D
+$ ruby 1.rb
+[
+    [0] false,
+    [1] 42,
+    [2] [
+        [0] "forty",
+        [1] "two"
+    ],
+    [3] {
+           :class => Time < Object,
+             :now => Fri Apr 02 19:55:53 -0700 2010,
+        :distance => 4.2e+43
+    }
+]
+
+$ cat > 2.rb
+require "awesome_print"
+data = { :now => Time.now, :class => Time.now.class, :distance => 42e42 }
+ap data, :indent => -2  # <-- Left align hash keys.
+^D
+$ ruby 2.rb
+{
+  :class    => Time < Object,
+  :now      => Fri Apr 02 19:55:53 -0700 2010,
+  :distance => 4.2e+43
+}
+
+$ cat > 3.rb
+require "awesome_print"
+data = [ false, 42, %w(forty two) ]
+data << data  # <-- Nested array.
+ap data, :multiline => false
+^D
+$ ruby 3.rb
+[ false, 42, [ "forty", "two" ], [...] ]
+
+$ cat > 4.rb
+require "awesome_print"
+class Hello
+  def self.world(x, y, z = nil, &blk)
+  end
+end
+ap Hello.methods - Class.methods
+^D
+$ ruby 4.rb
+[
+    [0] world(x, y, *z, &blk) Hello
+]
+
+$ cat > 5.rb
+require "awesome_print"
+ap (''.methods - Object.methods).grep(/!/)
+^D
+$ ruby 5.rb
+[
+    [ 0] capitalize!()           String
+    [ 1]      chomp!(*arg1)      String
+    [ 2]       chop!()           String
+    [ 3]     delete!(*arg1)      String
+    [ 4]   downcase!()           String
+    [ 5]     encode!(*arg1)      String
+    [ 6]       gsub!(*arg1)      String
+    [ 7]     lstrip!()           String
+    [ 8]       next!()           String
+    [ 9]    reverse!()           String
+    [10]     rstrip!()           String
+    [11]      slice!(*arg1)      String
+    [12]    squeeze!(*arg1)      String
+    [13]      strip!()           String
+    [14]        sub!(*arg1)      String
+    [15]       succ!()           String
+    [16]   swapcase!()           String
+    [17]         tr!(arg1, arg2) String
+    [18]       tr_s!(arg1, arg2) String
+    [19]     upcase!()           String
+]
+
+$ cat > 6.rb
+require "awesome_print"
+ap 42 == ap(42)
+^D
+$ ruby 6.rb
+42
+true
+$ cat 7.rb
+require "awesome_print"
+some_array = (1..1000).to_a
+ap some_array, :limit => true
+^D
+$ ruby 7.rb
+[
+    [  0] 1,
+    [  1] 2,
+    [  2] 3,
+    [  3] .. [996],
+    [997] 998,
+    [998] 999,
+    [999] 1000
+]
+
+$ cat 8.rb
+require "awesome_print"
+some_array = (1..1000).to_a
+ap some_array, :limit => 5
+^D
+$ ruby 8.rb
+[
+    [  0] 1,
+    [  1] 2,
+    [  2] .. [997],
+    [998] 999,
+    [999] 1000
+]
+```
+
+### Example (Rails console) ###
+```ruby
+$ rails console
+rails> require "awesome_print"
+rails> ap Account.limit(2).all
+[
+    [0] #<Account:0x1033220b8> {
+                     :id => 1,
+                :user_id => 5,
+            :assigned_to => 7,
+                   :name => "Hayes-DuBuque",
+                 :access => "Public",
+                :website => "http://www.hayesdubuque.com",
+        :toll_free_phone => "1-800-932-6571",
+                  :phone => "(111)549-5002",
+                    :fax => "(349)415-2266",
+             :deleted_at => nil,
+             :created_at => Sat, 06 Mar 2010 09:46:10 UTC +00:00,
+             :updated_at => Sat, 06 Mar 2010 16:33:10 UTC +00:00,
+                  :email => "info at hayesdubuque.com",
+        :background_info => nil
+    },
+    [1] #<Account:0x103321ff0> {
+                     :id => 2,
+                :user_id => 4,
+            :assigned_to => 4,
+                   :name => "Ziemann-Streich",
+                 :access => "Public",
+                :website => "http://www.ziemannstreich.com",
+        :toll_free_phone => "1-800-871-0619",
+                  :phone => "(042)056-1534",
+                    :fax => "(106)017-8792",
+             :deleted_at => nil,
+             :created_at => Tue, 09 Feb 2010 13:32:10 UTC +00:00,
+             :updated_at => Tue, 09 Feb 2010 20:05:01 UTC +00:00,
+                  :email => "info at ziemannstreich.com",
+        :background_info => nil
+    }
+]
+rails> ap Account
+class Account < ActiveRecord::Base {
+                 :id => :integer,
+            :user_id => :integer,
+        :assigned_to => :integer,
+               :name => :string,
+             :access => :string,
+            :website => :string,
+    :toll_free_phone => :string,
+              :phone => :string,
+                :fax => :string,
+         :deleted_at => :datetime,
+         :created_at => :datetime,
+         :updated_at => :datetime,
+              :email => :string,
+    :background_info => :string
+}
+rails>
+```
+
+### IRB integration ###
+To use awesome_print as default formatter in irb and Rails console add the following
+code to your ~/.irbrc file:
+
+```ruby
+require "awesome_print"
+AwesomePrint.irb!
+```
+
+### PRY integration ###
+If you miss awesome_print's way of formatting output, here's how you can use it in place
+of the formatting which comes with pry. Add the following code to your ~/.pryrc:
+
+```ruby
+require "awesome_print"
+AwesomePrint.pry!
+```
+
+### Logger Convenience Method ###
+awesome_print adds the 'ap' method to the Logger and ActiveSupport::BufferedLogger classes
+letting you call:
+
+    logger.ap object
+
+By default, this logs at the :debug level. You can override that globally with:
+
+    :log_level => :info
+
+in the custom defaults (see below). You can also override on a per call basis with:
+
+    logger.ap object, :warn
+
+### ActionView Convenience Method ###
+awesome_print adds the 'ap' method to the ActionView::Base class making it available
+within Rails templates. For example:
+
+    <%= ap @accounts.first %>   # ERB
+    != ap @accounts.first       # HAML
+
+With other web frameworks (ex: in Sinatra templates) you can explicitly request HTML
+formatting:
+
+    <%= ap @accounts.first, :html => true %>
+
+### Setting Custom Defaults ###
+You can set your own default options by creating ``.aprc`` file in your home
+directory. Within that file assign your  defaults to ``AwesomePrint.defaults``.
+For example:
+
+```ruby
+# ~/.aprc file.
+AwesomePrint.defaults = {
+  :indent => -2,
+  :color => {
+    :hash  => :pale,
+    :class => :white
+  }
+}
+```
+
+### Running Specs ###
+
+    $ gem install rspec           # RSpec 2.x is the requirement.
+    $ rake spec                   # Run the entire spec suite.
+    $ rspec spec/logger_spec.rb   # Run individual spec file.
+
+### Note on Patches/Pull Requests ###
+* Fork the project on Github.
+* Make your feature addition or bug fix.
+* Add specs for it, making sure $ rake spec is all green.
+* Commit, do not mess with rakefile, version, or history.
+* Send commit URL (*do not* send pull requests).
+
+### Contributors ###
+Special thanks goes to awesome team of contributors, namely:
+
+* 6fusion.com -- https://github.com/6fusion
+* Adam Doppelt -- https://github.com/gurgeous
+* Andrew O'Brien -- https://github.com/AndrewO
+* Andrew Horsman -- https://github.com/basicxman
+* Barry Allard -- https://github.com/steakknife
+* Benoit Daloze -- http://github.com/eregon
+* Brandon Zylstra -- https://github.com/brandondrew
+* Dan Lynn -- https://github.com/danlynn
+* Daniel Johnson -- https://github.com/adhd360
+* Daniel Bretoi -- http://github.com/danielb2
+* Eloy Duran -- http://github.com/alloy
+* Elpizo Choi -- https://github.com/fuJiin
+* Evan Senter -- https://github.com/evansenter
+* George . -- https://github.com/gardelea
+* Greg Weber -- https://github.com/gregwebs
+* Jan Vansteenkiste -- https://github.com/vStone
+* Jeff Felchner -- https://github.com/jfelchner
+* Jonathan Davies -- send your Github URL ;-)
+* Kevin Olbrich -- https://github.com/olbrich
+* Matthew Schulkind -- https://github.com/mschulkind
+* Mike McQuaid -- https://github.com/mikemcquaid
+* Nami-Doc -- https://github.com/Nami-Doc
+* Nicolas Viennot -- https://github.com/nviennot
+* Nikolaj Nikolajsen -- https://github.com/nikolajsen
+* Richard Hall -- https://github.com/richardardrichard
+* Ryan Schlesinger -- https://github.com/ryansch
+* Scott Hyndman -- https://github.com/shyndman
+* Sean Gallagher -- http://github.com/torandu
+* Stephan Hagemann -- https://github.com/shageman
+* Tim Harper -- http://github.com/timcharper
+* Tobias Crawley -- http://github.com/tobias
+* Thibaut Barrère -- https://github.com/thbar
+* Trevor Wennblom -- https://github.com/trevor
+* vfrride -- https://github.com/vfrride
+* Viktar Basharymau -- https://github.com/DNNX
+
+### License ###
+Copyright (c) 2010-2013 Michael Dvorkin
+
+http://www.dvorkin.net
+
+%w(mike dvorkin.net) * "@" || "twitter.com/mid"
+
+Released under the MIT license. See LICENSE file for details.
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..f2bc512
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,11 @@
+require "bundler"
+Bundler::GemHelper.install_tasks
+
+task :default => :spec
+
+desc "Run all awesome_print gem specs"
+task :spec do
+  # Run plain rspec command without RSpec::Core::RakeTask overrides.
+  exec "rspec -c spec"
+end
+
diff --git a/lib/ap.rb b/lib/ap.rb
new file mode 100755
index 0000000..793a9af
--- /dev/null
+++ b/lib/ap.rb
@@ -0,0 +1,10 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+#
+# Keeping this for backwards compatibility to allow
+# require "ap"
+#
+require File.dirname(__FILE__) + "/awesome_print"
diff --git a/lib/awesome_print.rb b/lib/awesome_print.rb
new file mode 100755
index 0000000..98d0c74
--- /dev/null
+++ b/lib/awesome_print.rb
@@ -0,0 +1,35 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+#
+# AwesomePrint might be loaded implicitly through ~/.irbrc or ~/.pryrc
+# so do nothing for subsequent requires.
+#
+unless defined?(AwesomePrint::Inspector)
+  %w(array string method object class kernel).each do |file|
+    require File.dirname(__FILE__) + "/awesome_print/core_ext/#{file}"
+  end
+
+  require File.dirname(__FILE__) + "/awesome_print/inspector"
+  require File.dirname(__FILE__) + "/awesome_print/formatter"
+  require File.dirname(__FILE__) + "/awesome_print/version"
+  require File.dirname(__FILE__) + "/awesome_print/core_ext/logger" if defined?(Logger)
+  #
+  # Load the following under normal circumstances as well as in Rails
+  # console when required from ~/.irbrc or ~/.pryrc.
+  #
+  require File.dirname(__FILE__) + "/awesome_print/ext/active_record"  if defined?(ActiveRecord)  || AwesomePrint.rails_console?
+  require File.dirname(__FILE__) + "/awesome_print/ext/active_support" if defined?(ActiveSupport) || AwesomePrint.rails_console?
+  #
+  # Load remaining extensions.
+  #
+  require File.dirname(__FILE__) + "/awesome_print/ext/action_view"    if defined?(ActionView::Base)
+  require File.dirname(__FILE__) + "/awesome_print/ext/mongo_mapper"   if defined?(MongoMapper)
+  require File.dirname(__FILE__) + "/awesome_print/ext/mongoid"        if defined?(Mongoid)
+  require File.dirname(__FILE__) + "/awesome_print/ext/nokogiri"       if defined?(Nokogiri)
+  require File.dirname(__FILE__) + "/awesome_print/ext/no_brainer"     if defined?(NoBrainer)
+  require File.dirname(__FILE__) + "/awesome_print/ext/ripple"         if defined?(Ripple)
+  require File.dirname(__FILE__) + "/awesome_print/ext/sequel"         if defined?(Sequel)
+end
diff --git a/lib/awesome_print/core_ext/array.rb b/lib/awesome_print/core_ext/array.rb
new file mode 100644
index 0000000..ec1a1cd
--- /dev/null
+++ b/lib/awesome_print/core_ext/array.rb
@@ -0,0 +1,81 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+#
+# The following makes it possible to invoke awesome_print while performing
+# operations on method arrays, ex:
+#
+#   ap [].methods - Object.methods
+#   ap ''.methods.grep(/!|\?/)
+#
+# If you could think of a better way please let me know :-)
+#
+class Array #:nodoc:
+  [ :-, :& ].each do |operator|
+    original_operator = instance_method(operator)
+
+    define_method operator do |*args|
+      arr = original_operator.bind(self).call(*args)
+      if self.instance_variable_defined?('@__awesome_methods__')
+        arr.instance_variable_set('@__awesome_methods__', self.instance_variable_get('@__awesome_methods__'))
+        arr.sort! { |a, b| a.to_s <=> b.to_s }  # Need the block since Ruby 1.8.x can't sort arrays of symbols.
+      end
+      arr
+    end
+  end
+  #
+  # Intercepting Array#grep needs a special treatment since grep accepts
+  # an optional block.
+  #
+  alias :original_grep :grep
+  def grep(pattern, &blk)
+    #
+    # The following looks rather insane and I've sent numerous hours trying
+    # to figure it out. The problem is that if grep gets called with the
+    # block, for example:
+    #
+    #    [].methods.grep(/(.+?)_by/) { $1.to_sym }
+    #
+    # ...then simple:
+    #
+    #    original_grep(pattern, &blk)
+    #
+    # doesn't set $1 within the grep block which causes nil.to_sym failure.
+    # The workaround below has been tested with Ruby 1.8.7/Rails 2.3.8 and
+    # Ruby 1.9.2/Rails 3.0.0. For more info see the following thread dating
+    # back to 2003 when Ruby 1.8.0 was as fresh off the grill as Ruby 1.9.2
+    # is in 2010 :-)
+    #
+    # http://www.justskins.com/forums/bug-when-rerouting-string-52852.html
+    #
+    # BTW, if you figure out a better way of intercepting Array#grep please
+    # let me know: twitter.com/mid -- or just say hi so I know you've read
+    # the comment :-)
+    #
+    arr = unless blk
+      original_grep(pattern)
+    else
+      original_grep(pattern) do |match|
+        #
+        # The binding can only be used with Ruby-defined methods, therefore
+        # we must rescue potential "ArgumentError: Can't create Binding from
+        # C level Proc" error.
+        #
+        # For example, the following raises ArgumentError since #succ method
+        # is defined in C.
+        #
+        # [ 0, 1, 2, 3, 4 ].grep(1..2, &:succ)
+        #
+        eval("%Q/#{match.to_s.gsub('/', '\/')}/ =~ #{pattern.inspect}", blk.binding) rescue ArgumentError
+        yield match
+      end
+    end
+    if self.instance_variable_defined?('@__awesome_methods__')
+      arr.instance_variable_set('@__awesome_methods__', self.instance_variable_get('@__awesome_methods__'))
+      arr.reject! { |item| !(item.is_a?(Symbol) || item.is_a?(String)) } # grep block might return crap.
+    end
+    arr
+  end
+end
diff --git a/lib/awesome_print/core_ext/class.rb b/lib/awesome_print/core_ext/class.rb
new file mode 100644
index 0000000..5faac7e
--- /dev/null
+++ b/lib/awesome_print/core_ext/class.rb
@@ -0,0 +1,22 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+class Class #:nodoc:
+  #
+  # Intercept methods below to inject @__awesome_print__ instance variable
+  # so we know it is the *methods* array when formatting an array.
+  #
+  # Remaining public/private etc. '_methods' are handled in core_ext/object.rb.
+  #
+  %w(instance_methods private_instance_methods protected_instance_methods public_instance_methods).each do |name|
+    original_method = instance_method(name)
+
+    define_method name do |*args|
+      methods = original_method.bind(self).call(*args)
+      methods.instance_variable_set('@__awesome_methods__', self)
+      methods
+    end
+  end
+end
diff --git a/lib/awesome_print/core_ext/kernel.rb b/lib/awesome_print/core_ext/kernel.rb
new file mode 100644
index 0000000..a87d19c
--- /dev/null
+++ b/lib/awesome_print/core_ext/kernel.rb
@@ -0,0 +1,26 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+module Kernel
+
+  def ai(options = {})
+    ap = AwesomePrint::Inspector.new(options)
+    awesome = ap.awesome self
+    if options[:html]
+      awesome = "<pre>#{awesome}</pre>"
+      awesome = awesome.html_safe if defined? ActiveSupport
+    end
+    awesome
+  end
+  alias :awesome_inspect :ai
+
+  def ap(object, options = {})
+    puts object.ai(options)
+    object unless AwesomePrint.console?
+  end
+  alias :awesome_print :ap
+
+  module_function :ap
+end
diff --git a/lib/awesome_print/core_ext/logger.rb b/lib/awesome_print/core_ext/logger.rb
new file mode 100644
index 0000000..516609c
--- /dev/null
+++ b/lib/awesome_print/core_ext/logger.rb
@@ -0,0 +1,20 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+module AwesomePrint
+  module Logger
+
+    # Add ap method to logger
+    #------------------------------------------------------------------------------
+    def ap(object, level = nil)
+      level ||= AwesomePrint.defaults[:log_level] if AwesomePrint.defaults
+      level ||= :debug
+      send level, object.ai
+    end
+  end
+end
+
+Logger.send(:include, AwesomePrint::Logger)
+ActiveSupport::BufferedLogger.send(:include, AwesomePrint::Logger) if defined?(ActiveSupport::BufferedLogger)
diff --git a/lib/awesome_print/core_ext/method.rb b/lib/awesome_print/core_ext/method.rb
new file mode 100644
index 0000000..a30b148
--- /dev/null
+++ b/lib/awesome_print/core_ext/method.rb
@@ -0,0 +1,21 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+#
+# Method#name was intorduced in Ruby 1.8.7 so we define it here as necessary.
+#
+unless nil.method(:class).respond_to?(:name)
+  class Method
+    def name
+      inspect.split(/[#.>]/)[-1]
+    end
+  end
+
+  class UnboundMethod
+    def name
+      inspect.split(/[#.>]/)[-1]
+    end
+  end
+end
\ No newline at end of file
diff --git a/lib/awesome_print/core_ext/object.rb b/lib/awesome_print/core_ext/object.rb
new file mode 100644
index 0000000..c58e279
--- /dev/null
+++ b/lib/awesome_print/core_ext/object.rb
@@ -0,0 +1,22 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+class Object #:nodoc:
+  #
+  # Intercept methods below to inject @__awesome_print__ instance variable
+  # so we know it is the *methods* array when formatting an array.
+  #
+  # Remaining instance '_methods' are handled in core_ext/class.rb.
+  #
+  %w(methods private_methods protected_methods public_methods singleton_methods).each do |name|
+    original_method = instance_method(name)
+
+    define_method name do |*args|
+      methods = original_method.bind(self).call(*args)
+      methods.instance_variable_set('@__awesome_methods__', self)
+      methods
+    end
+  end
+end
diff --git a/lib/awesome_print/core_ext/string.rb b/lib/awesome_print/core_ext/string.rb
new file mode 100644
index 0000000..3fa1ed9
--- /dev/null
+++ b/lib/awesome_print/core_ext/string.rb
@@ -0,0 +1,31 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+class String
+  #
+  # ANSI color codes:
+  #   \e => escape
+  #   30 => color base
+  #    1 => bright
+  #    0 => normal
+  #
+  # For HTML coloring we use <kbd> tag instead of <span> to require monospace
+  # font. Note that beloved <tt> has been removed from HTML5.
+  #
+  %w(gray red green yellow blue purple cyan white).zip(
+  %w(black darkred darkgreen brown navy darkmagenta darkcyan slategray)).each_with_index do |(color, shade), i|
+    define_method color do |*html|
+      html[0] ? %Q|<kbd style="color:#{color}">#{self}</kbd>| : "\e[1;#{30+i}m#{self}\e[0m"
+    end
+
+    define_method "#{color}ish" do |*html|
+      html[0] ? %Q|<kbd style="color:#{shade}">#{self}</kbd>| : "\e[0;#{30+i}m#{self}\e[0m"
+    end
+  end
+
+  alias :black :grayish
+  alias :pale  :whiteish
+
+end
diff --git a/lib/awesome_print/ext/action_view.rb b/lib/awesome_print/ext/action_view.rb
new file mode 100644
index 0000000..c34e8d0
--- /dev/null
+++ b/lib/awesome_print/ext/action_view.rb
@@ -0,0 +1,18 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+module AwesomePrint
+  module ActionView
+
+    # Use HTML colors and add default "debug_dump" class to the resulting HTML.
+    def ap_debug(object, options = {})
+      object.ai(options.merge(:html => true)).sub(/^<pre([\s>])/, '<pre class="debug_dump"\\1')
+    end
+
+    alias_method :ap, :ap_debug
+  end
+end
+
+ActionView::Base.send(:include, AwesomePrint::ActionView)
diff --git a/lib/awesome_print/ext/active_record.rb b/lib/awesome_print/ext/active_record.rb
new file mode 100644
index 0000000..b15f3c6
--- /dev/null
+++ b/lib/awesome_print/ext/active_record.rb
@@ -0,0 +1,69 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+module AwesomePrint
+  module ActiveRecord
+
+    def self.included(base)
+      base.send :alias_method, :cast_without_active_record, :cast
+      base.send :alias_method, :cast, :cast_with_active_record
+    end
+
+    # Add ActiveRecord class names to the dispatcher pipeline.
+    #------------------------------------------------------------------------------
+    def cast_with_active_record(object, type)
+      cast = cast_without_active_record(object, type)
+      return cast if !defined?(::ActiveRecord)
+
+      if object.is_a?(::ActiveRecord::Base)
+        cast = :active_record_instance
+      elsif object.is_a?(Class) && object.ancestors.include?(::ActiveRecord::Base)
+        cast = :active_record_class
+      elsif type == :activerecord_relation
+        cast = :array
+      end
+      cast
+    end
+
+    private
+
+    # Format ActiveRecord instance object.
+    #
+    # NOTE: by default only instance attributes (i.e. columns) are shown. To format
+    # ActiveRecord instance as regular object showing its instance variables and
+    # accessors use :raw => true option:
+    #
+    # ap record, :raw => true
+    #
+    #------------------------------------------------------------------------------
+    def awesome_active_record_instance(object)
+      return object.inspect if !defined?(::ActiveSupport::OrderedHash)
+      return awesome_object(object) if @options[:raw]
+
+      data = object.class.column_names.inject(::ActiveSupport::OrderedHash.new) do |hash, name|
+        if object.has_attribute?(name) || object.new_record?
+          value = object.respond_to?(name) ? object.send(name) : object.read_attribute(name)
+          hash[name.to_sym] = value
+        end
+        hash
+      end
+      "#{object} " << awesome_hash(data)
+    end
+
+    # Format ActiveRecord class object.
+    #------------------------------------------------------------------------------
+    def awesome_active_record_class(object)
+      return object.inspect if !defined?(::ActiveSupport::OrderedHash) || !object.respond_to?(:columns) || object.to_s == "ActiveRecord::Base"
+
+      data = object.columns.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
+        hash[c.name.to_sym] = c.type
+        hash
+      end
+      "class #{object} < #{object.superclass} " << awesome_hash(data)
+    end
+  end
+end
+
+AwesomePrint::Formatter.send(:include, AwesomePrint::ActiveRecord)
diff --git a/lib/awesome_print/ext/active_support.rb b/lib/awesome_print/ext/active_support.rb
new file mode 100644
index 0000000..2774990
--- /dev/null
+++ b/lib/awesome_print/ext/active_support.rb
@@ -0,0 +1,47 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+module AwesomePrint
+  module ActiveSupport
+
+    def self.included(base)
+      base.send :alias_method, :cast_without_active_support, :cast
+      base.send :alias_method, :cast, :cast_with_active_support
+    end
+
+    def cast_with_active_support(object, type)
+      cast = cast_without_active_support(object, type)
+      if defined?(::ActiveSupport) && defined?(::HashWithIndifferentAccess)
+        if (defined?(::ActiveSupport::TimeWithZone) && object.is_a?(::ActiveSupport::TimeWithZone)) || object.is_a?(::Date)
+          cast = :active_support_time
+        elsif object.is_a?(::HashWithIndifferentAccess)
+          cast = :hash_with_indifferent_access
+        end
+      end
+      cast
+    end
+
+    # Format ActiveSupport::TimeWithZone as standard Time.
+    #------------------------------------------------------------------------------
+    def awesome_active_support_time(object)
+      colorize(object.inspect, :time)
+    end
+
+    # Format HashWithIndifferentAccess as standard Hash.
+    #------------------------------------------------------------------------------
+    def awesome_hash_with_indifferent_access(object)
+      awesome_hash(object)
+    end
+  end
+end
+
+AwesomePrint::Formatter.send(:include, AwesomePrint::ActiveSupport)
+#
+# Colorize Rails logs.
+#
+if defined?(ActiveSupport::LogSubscriber)
+  AwesomePrint.force_colors! ActiveSupport::LogSubscriber.colorize_logging
+end
+
diff --git a/lib/awesome_print/ext/mongo_mapper.rb b/lib/awesome_print/ext/mongo_mapper.rb
new file mode 100644
index 0000000..4e7a81a
--- /dev/null
+++ b/lib/awesome_print/ext/mongo_mapper.rb
@@ -0,0 +1,121 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+module AwesomePrint
+  module MongoMapper
+
+    def self.included(base)
+      base.send :alias_method, :cast_without_mongo_mapper, :cast
+      base.send :alias_method, :cast, :cast_with_mongo_mapper
+    end
+
+    # Add MongoMapper class names to the dispatcher pipeline.
+    #------------------------------------------------------------------------------
+    def cast_with_mongo_mapper(object, type)
+      apply_default_mongo_mapper_options
+      cast = cast_without_mongo_mapper(object, type)
+
+      if defined?(::MongoMapper::Document)
+        if object.is_a?(Class) && (object.ancestors & [ ::MongoMapper::Document, ::MongoMapper::EmbeddedDocument ]).size > 0
+          cast = :mongo_mapper_class
+        elsif object.is_a?(::MongoMapper::Document) || object.is_a?(::MongoMapper::EmbeddedDocument)
+          cast = :mongo_mapper_instance
+        elsif object.is_a?(::MongoMapper::Plugins::Associations::Base)
+          cast = :mongo_mapper_association
+        elsif object.is_a?(::BSON::ObjectId)
+          cast = :mongo_mapper_bson_id
+        end
+      end
+
+      cast
+    end
+
+    # Format MongoMapper class object.
+    #------------------------------------------------------------------------------
+    def awesome_mongo_mapper_class(object)
+      return object.inspect if !defined?(::ActiveSupport::OrderedHash) || !object.respond_to?(:keys)
+
+      data = object.keys.sort.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
+        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
+
+    # Format MongoMapper instance object.
+    #
+    # NOTE: by default only instance attributes (i.e. keys) are shown. To format
+    # MongoMapper instance as regular object showing its instance variables and
+    # accessors use :raw => true option:
+    #
+    # ap record, :raw => true
+    #
+    #------------------------------------------------------------------------------
+    def awesome_mongo_mapper_instance(object)
+      return object.inspect if !defined?(::ActiveSupport::OrderedHash)
+      return awesome_object(object) if @options[:raw]
+
+      data = object.keys.keys.sort_by{|k| k}.inject(::ActiveSupport::OrderedHash.new) do |hash, name|
+        hash[name] = object[name]
+        hash
+      end
+
+      # 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)
+      return awesome_object(object) if @options[:raw]
+
+      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 BSON::ObjectId
+    #------------------------------------------------------------------------------
+    def awesome_mongo_mapper_bson_id(object)
+      object.inspect
+    end
+
+    private
+
+    def apply_default_mongo_mapper_options
+      @options[:color][:assoc] ||= :greenish
+      @options[:mongo_mapper]  ||= {
+        :show_associations => false, # Display association data for MongoMapper documents and classes.
+        :inline_embedded => false    # Display embedded associations inline with MongoMapper documents.
+      }
+    end
+  end
+end
+
+AwesomePrint::Formatter.send(:include, AwesomePrint::MongoMapper)
diff --git a/lib/awesome_print/ext/mongoid.rb b/lib/awesome_print/ext/mongoid.rb
new file mode 100644
index 0000000..7f8b8e0
--- /dev/null
+++ b/lib/awesome_print/ext/mongoid.rb
@@ -0,0 +1,65 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+module AwesomePrint
+  module Mongoid
+
+    def self.included(base)
+      base.send :alias_method, :cast_without_mongoid, :cast
+      base.send :alias_method, :cast, :cast_with_mongoid
+    end
+
+    # Add Mongoid class names to the dispatcher pipeline.
+    #------------------------------------------------------------------------------
+    def cast_with_mongoid(object, type)
+      cast = cast_without_mongoid(object, type)
+      if defined?(::Mongoid::Document)
+        if object.is_a?(Class) && object.ancestors.include?(::Mongoid::Document)
+          cast = :mongoid_class
+        elsif object.class.ancestors.include?(::Mongoid::Document)
+          cast = :mongoid_document
+        elsif (defined?(::BSON) && object.is_a?(::BSON::ObjectId)) || (defined?(::Moped) && object.is_a?(::Moped::BSON::ObjectId))
+          cast = :mongoid_bson_id
+        end
+      end
+      cast
+    end
+
+    # Format Mongoid class object.
+    #------------------------------------------------------------------------------
+    def awesome_mongoid_class(object)
+      return object.inspect if !defined?(::ActiveSupport::OrderedHash) || !object.respond_to?(:fields)
+
+      data = object.fields.sort_by { |key| key }.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
+        hash[c[1].name.to_sym] = (c[1].type || "undefined").to_s.underscore.intern
+        hash
+      end
+      "class #{object} < #{object.superclass} " << awesome_hash(data)
+    end
+
+    # Format Mongoid Document object.
+    #------------------------------------------------------------------------------
+    def awesome_mongoid_document(object)
+      return object.inspect if !defined?(::ActiveSupport::OrderedHash)
+
+      data = (object.attributes || {}).sort_by { |key| key }.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
+        hash[c[0].to_sym] = c[1]
+        hash
+      end
+      if !object.errors.empty?
+        data = {:errors => object.errors, :attributes => data}
+      end
+      "#{object} #{awesome_hash(data)}"
+    end
+
+    # Format BSON::ObjectId
+    #------------------------------------------------------------------------------
+    def awesome_mongoid_bson_id(object)
+      object.inspect
+    end
+  end
+end
+
+AwesomePrint::Formatter.send(:include, AwesomePrint::Mongoid)
diff --git a/lib/awesome_print/ext/no_brainer.rb b/lib/awesome_print/ext/no_brainer.rb
new file mode 100644
index 0000000..431509d
--- /dev/null
+++ b/lib/awesome_print/ext/no_brainer.rb
@@ -0,0 +1,58 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+module AwesomePrint
+  module NoBrainer
+
+    def self.included(base)
+      base.send :alias_method, :cast_without_no_brainer, :cast
+      base.send :alias_method, :cast, :cast_with_no_brainer
+    end
+
+    # Add NoBrainer class names to the dispatcher pipeline.
+    #------------------------------------------------------------------------------
+    def cast_with_no_brainer(object, type)
+      cast = cast_without_no_brainer(object, type)
+      if defined?(::NoBrainer::Document)
+        if object.is_a?(Class) && object.ancestors.include?(::NoBrainer::Document)
+          cast = :no_brainer_class
+        elsif object.class.ancestors.include?(::NoBrainer::Document)
+          cast = :no_brainer_document
+        end
+      end
+      cast
+    end
+
+    # Format NoBrainer class object.
+    #------------------------------------------------------------------------------
+    def awesome_no_brainer_class(object)
+      return object.inspect if !defined?(::ActiveSupport::OrderedHash) || !object.respond_to?(:fields)
+
+      # We want id first
+      data = object.fields.sort_by { |key| key[0] == :id ? '_id' : key[0].to_s }.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
+        hash[c[0]] = :object
+        hash
+      end
+      "class #{object} < #{object.superclass} " << awesome_hash(data)
+    end
+
+    # Format NoBrainer Document object.
+    #------------------------------------------------------------------------------
+    def awesome_no_brainer_document(object)
+      return object.inspect if !defined?(::ActiveSupport::OrderedHash)
+
+      data = object.attributes.sort_by { |key| key }.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
+        hash[c[0].to_sym] = c[1]
+        hash
+      end
+      if !object.errors.empty?
+        data = {:errors => object.errors, :attributes => data}
+      end
+      "#{object} #{awesome_hash(data)}"
+    end
+  end
+end
+
+AwesomePrint::Formatter.send(:include, AwesomePrint::NoBrainer)
diff --git a/lib/awesome_print/ext/nokogiri.rb b/lib/awesome_print/ext/nokogiri.rb
new file mode 100644
index 0000000..4d26c92
--- /dev/null
+++ b/lib/awesome_print/ext/nokogiri.rb
@@ -0,0 +1,45 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+module AwesomePrint
+  module Nokogiri
+
+    def self.included(base)
+      base.send :alias_method, :cast_without_nokogiri, :cast
+      base.send :alias_method, :cast, :cast_with_nokogiri
+    end
+
+    # Add Nokogiri XML Node and NodeSet names to the dispatcher pipeline.
+    #------------------------------------------------------------------------------
+    def cast_with_nokogiri(object, type)
+      cast = cast_without_nokogiri(object, type)
+      if (defined?(::Nokogiri::XML::Node) && object.is_a?(::Nokogiri::XML::Node)) || 
+         (defined?(::Nokogiri::XML::NodeSet) && object.is_a?(::Nokogiri::XML::NodeSet))
+        cast = :nokogiri_xml_node
+      end
+      cast
+    end
+
+    #------------------------------------------------------------------------------
+    def awesome_nokogiri_xml_node(object)
+      if object.is_a?(::Nokogiri::XML::NodeSet) && object.empty?
+        return "[]"
+      end
+      xml = object.to_xml(:indent => 2)
+      #
+      # Colorize tag, id/class name, and contents.
+      #
+      xml.gsub!(/(<)(\/?[A-Za-z1-9]+)/) { |tag| "#{$1}#{colorize($2, :keyword)}" }
+      xml.gsub!(/(id|class)="[^"]+"/i) { |id| colorize(id, :class) }
+      xml.gsub!(/>([^<]+)</) do |contents|
+        contents = colorize($1, :trueclass) if contents && !contents.empty?
+        ">#{contents}<"
+      end
+      xml
+    end
+  end
+end
+
+AwesomePrint::Formatter.send(:include, AwesomePrint::Nokogiri)
diff --git a/lib/awesome_print/ext/ripple.rb b/lib/awesome_print/ext/ripple.rb
new file mode 100644
index 0000000..a98927a
--- /dev/null
+++ b/lib/awesome_print/ext/ripple.rb
@@ -0,0 +1,72 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+module AwesomePrint
+  module Ripple
+
+    def self.included(base)
+      base.send :alias_method, :cast_without_ripple, :cast
+      base.send :alias_method, :cast, :cast_with_ripple
+    end
+
+    # Add Ripple class names to the dispatcher pipeline.
+    #------------------------------------------------------------------------------
+    def cast_with_ripple(object, type)
+      cast = cast_without_ripple(object, type)
+      return cast if !defined?(::Ripple)
+
+      if object.is_a?(::Ripple::AttributeMethods) # Module used to access attributes across documents and embedded documents
+        cast = :ripple_document_instance
+      elsif object.is_a?(::Ripple::Properties)    # Used to access property metadata on Ripple classes
+        cast = :ripple_document_class
+      end
+      cast
+    end
+
+    private
+
+    # Format Ripple instance object.
+    #
+    # NOTE: by default only instance attributes are shown. To format a Ripple document instance
+    # as a regular object showing its instance variables and accessors use :raw => true option:
+    #
+    # ap document, :raw => true
+    #
+    #------------------------------------------------------------------------------
+    def awesome_ripple_document_instance(object)
+      return object.inspect if !defined?(::ActiveSupport::OrderedHash)
+      return awesome_object(object) if @options[:raw]
+      exclude_assoc = @options[:exclude_assoc] or @options[:exclude_associations]
+
+      data = object.attributes.inject(::ActiveSupport::OrderedHash.new) do |hash, (name, value)|
+        hash[name.to_sym] = object.send(name)
+        hash
+      end
+
+      unless exclude_assoc
+        data = object.class.embedded_associations.inject(data) do |hash, assoc|
+          hash[assoc.name] = object.get_proxy(assoc) # Should always be array or Ripple::EmbeddedDocument for embedded associations
+          hash
+        end
+      end
+
+      "##{object} " << awesome_hash(data)
+    end
+
+    # Format Ripple class object.
+    #------------------------------------------------------------------------------
+    def awesome_ripple_document_class(object)
+      return object.inspect if !defined?(::ActiveSupport::OrderedHash) || !object.respond_to?(:properties)
+
+      data = object.properties.inject(::ActiveSupport::OrderedHash.new) do |hash, (name, defn)|
+        hash[name.to_sym] = defn.type.to_s.downcase.to_sym
+        hash
+      end
+      "class #{object} < #{object.superclass} " << awesome_hash(data)
+    end
+  end
+end
+
+AwesomePrint::Formatter.send(:include, AwesomePrint::Ripple)
diff --git a/lib/awesome_print/ext/sequel.rb b/lib/awesome_print/ext/sequel.rb
new file mode 100644
index 0000000..75cfa23
--- /dev/null
+++ b/lib/awesome_print/ext/sequel.rb
@@ -0,0 +1,57 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+module AwesomePrint
+  module Sequel
+
+    def self.included(base)
+      base.send :alias_method, :cast_without_sequel, :cast
+      base.send :alias_method, :cast, :cast_with_sequel
+    end
+
+    # Add Sequel class names to the dispatcher pipeline.
+    #------------------------------------------------------------------------------
+    def cast_with_sequel(object, type)
+      cast = cast_without_sequel(object, type)
+      if defined?(::Sequel::Model) && object.is_a?(::Sequel::Model)
+        cast = :sequel_document
+      elsif defined?(::Sequel::Model) && object.is_a?(Class) && object.ancestors.include?(::Sequel::Model)
+        cast = :sequel_model_class
+      elsif defined?(::Sequel::Mysql2::Dataset) && object.class.ancestors.include?(::Sequel::Mysql2::Dataset)
+        cast = :sequel_dataset
+      end
+      cast
+    end
+
+    # Format Sequel Document object.
+    #------------------------------------------------------------------------------
+    def awesome_sequel_document(object)
+      data = object.values.sort_by { |key| key.to_s }.inject({}) do |hash, c|
+        hash[c[0].to_sym] = c[1]
+        hash
+      end
+      if !object.errors.empty?
+        data = {:errors => object.errors, :values => data}
+      end
+      "#{object} #{awesome_hash(data)}"
+    end
+
+    # Format Sequel Dataset object.
+    #------------------------------------------------------------------------------
+    def awesome_sequel_dataset(dataset)
+      [awesome_array(dataset.to_a), awesome_print(dataset.sql)].join("\n")
+    end
+
+    # Format Sequel Model class.
+    #------------------------------------------------------------------------------
+    def awesome_sequel_model_class(object)
+      data = object.db_schema.inject({}) {|h, (name,data)| h.merge(name => data[:db_type])}
+      "class #{object} < #{object.superclass} " << awesome_hash(data)
+    end
+  end
+
+end
+
+AwesomePrint::Formatter.send(:include, AwesomePrint::Sequel)
diff --git a/lib/awesome_print/formatter.rb b/lib/awesome_print/formatter.rb
new file mode 100755
index 0000000..3019c50
--- /dev/null
+++ b/lib/awesome_print/formatter.rb
@@ -0,0 +1,407 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+autoload :CGI, "cgi"
+require "shellwords"
+
+module AwesomePrint
+  class Formatter
+
+    CORE = [ :array, :bigdecimal, :class, :dir, :file, :hash, :method, :rational, :set, :struct, :unboundmethod ]
+    DEFAULT_LIMIT_SIZE = 7
+
+    def initialize(inspector)
+      @inspector   = inspector
+      @options     = inspector.options
+      @indentation = @options[:indent].abs
+    end
+
+    # Main entry point to format an object.
+    #------------------------------------------------------------------------------
+    def format(object, type = nil)
+      core_class = cast(object, type)
+      awesome = if core_class != :self
+        send(:"awesome_#{core_class}", object) # Core formatters.
+      else
+        awesome_self(object, type) # Catch all that falls back to object.inspect.
+      end
+      awesome
+    end
+
+    # Hook this when adding custom formatters. Check out lib/awesome_print/ext
+    # directory for custom formatters that ship with awesome_print.
+    #------------------------------------------------------------------------------
+    def cast(object, type)
+      CORE.grep(type)[0] || :self
+    end
+
+    # Pick the color and apply it to the given string as necessary.
+    #------------------------------------------------------------------------------
+    def colorize(str, type)
+      str = CGI.escapeHTML(str) if @options[:html]
+      if @options[:plain] || !@options[:color][type] || !@inspector.colorize?
+        str
+      #
+      # Check if the string color method is defined by awesome_print and accepts
+      # html parameter or it has been overriden by some gem such as colorize.
+      #
+      elsif str.method(@options[:color][type]).arity == -1 # Accepts html parameter.
+        str.send(@options[:color][type], @options[:html])
+      else
+        str = %Q|<kbd style="color:#{@options[:color][type]}">#{str}</kbd>| if @options[:html]
+        str.send(@options[:color][type])
+      end
+    end
+
+
+    private
+
+    # Catch all method to format an arbitrary object.
+    #------------------------------------------------------------------------------
+    def awesome_self(object, type)
+      if @options[:raw] && object.instance_variables.any?
+        awesome_object(object)
+      elsif object == ENV
+        awesome_hash(object.to_hash)
+      else
+        colorize(object.inspect.to_s, type)
+      end
+    end
+
+    # Format an array.
+    #------------------------------------------------------------------------------
+    def awesome_array(a)
+      return "[]" if a == []
+
+      if a.instance_variable_defined?('@__awesome_methods__')
+        methods_array(a)
+      elsif @options[:multiline]
+        width = (a.size - 1).to_s.size 
+
+        data = a.inject([]) do |arr, item|
+          index = indent
+          index << colorize("[#{arr.size.to_s.rjust(width)}] ", :array) if @options[:index]
+          indented do
+            arr << (index << @inspector.awesome(item))
+          end
+        end
+
+        data = limited(data, width) if should_be_limited?
+        "[\n" << data.join(",\n") << "\n#{outdent}]"
+      else
+        "[ " << a.map{ |item| @inspector.awesome(item) }.join(", ") << " ]"
+      end
+    end
+
+    # Format a hash. If @options[:indent] if negative left align hash keys.
+    #------------------------------------------------------------------------------
+    def awesome_hash(h)
+      return "{}" if h == {}
+
+      keys = @options[:sort_keys] ? h.keys.sort { |a, b| a.to_s <=> b.to_s } : h.keys
+      data = keys.map do |key|
+        plain_single_line do
+          [ @inspector.awesome(key), h[key] ]
+        end
+      end
+      
+      width = data.map { |key, | key.size }.max || 0
+      width += @indentation if @options[:indent] > 0
+  
+      data = data.map do |key, value|
+        indented do
+          align(key, width) << colorize(" => ", :hash) << @inspector.awesome(value)
+        end
+      end
+
+      data = limited(data, width, :hash => true) if should_be_limited?
+      if @options[:multiline]
+        "{\n" << data.join(",\n") << "\n#{outdent}}"
+      else
+        "{ #{data.join(', ')} }"
+      end
+    end
+
+    # Format an object.
+    #------------------------------------------------------------------------------
+    def awesome_object(o)
+      vars = o.instance_variables.map do |var|
+        property = var.to_s[1..-1].to_sym # to_s because of some monkey patching done by Puppet.
+        accessor = if o.respond_to?(:"#{property}=")
+          o.respond_to?(property) ? :accessor : :writer
+        else
+          o.respond_to?(property) ? :reader : nil
+        end
+        if accessor
+          [ "attr_#{accessor} :#{property}", var ]
+        else
+          [ var.to_s, var ]
+        end
+      end
+
+      data = vars.sort.map do |declaration, var|
+        key = left_aligned do
+          align(declaration, declaration.size)
+        end
+
+        unless @options[:plain]
+          if key =~ /(@\w+)/
+            key.sub!($1, colorize($1, :variable))
+          else
+            key.sub!(/(attr_\w+)\s(\:\w+)/, "#{colorize('\\1', :keyword)} #{colorize('\\2', :method)}")
+          end
+        end
+        indented do
+          key << colorize(" = ", :hash) + @inspector.awesome(o.instance_variable_get(var))
+        end
+      end
+      if @options[:multiline]
+        "#<#{awesome_instance(o)}\n#{data.join(%Q/,\n/)}\n#{outdent}>"
+      else
+        "#<#{awesome_instance(o)} #{data.join(', ')}>"
+      end
+    end
+
+    # Format a set.
+    #------------------------------------------------------------------------------
+    def awesome_set(s)
+      awesome_array(s.to_a)
+    end
+
+    # Format a Struct.
+    #------------------------------------------------------------------------------
+    def awesome_struct(s)
+      #
+      # The code is slightly uglier because of Ruby 1.8.6 quirks:
+      # awesome_hash(Hash[s.members.zip(s.values)]) <-- ArgumentError: odd number of arguments for Hash)
+      # awesome_hash(Hash[*s.members.zip(s.values).flatten]) <-- s.members returns strings, not symbols.
+      #
+      hash = {}
+      s.each_pair { |key, value| hash[key] = value }
+      awesome_hash(hash)
+    end
+
+    # Format Class object.
+    #------------------------------------------------------------------------------
+    def awesome_class(c)
+      if superclass = c.superclass # <-- Assign and test if nil.
+        colorize("#{c.inspect} < #{superclass}", :class)
+      else
+        colorize(c.inspect, :class)
+      end
+    end
+
+    # Format File object.
+    #------------------------------------------------------------------------------
+    def awesome_file(f)
+      ls = File.directory?(f) ? `ls -adlF #{f.path.shellescape}` : `ls -alF #{f.path.shellescape}`
+      colorize(ls.empty? ? f.inspect : "#{f.inspect}\n#{ls.chop}", :file)
+    end
+
+    # Format Dir object.
+    #------------------------------------------------------------------------------
+    def awesome_dir(d)
+      ls = `ls -alF #{d.path.shellescape}`
+      colorize(ls.empty? ? d.inspect : "#{d.inspect}\n#{ls.chop}", :dir)
+    end
+
+    # Format BigDecimal object.
+    #------------------------------------------------------------------------------
+    def awesome_bigdecimal(n)
+      colorize(n.to_s("F"), :bigdecimal)
+    end
+
+    # Format Rational object.
+    #------------------------------------------------------------------------------
+    def awesome_rational(n)
+      colorize(n.to_s, :rational)
+    end
+
+    # Format a method.
+    #------------------------------------------------------------------------------
+    def awesome_method(m)
+      name, args, owner = method_tuple(m)
+      "#{colorize(owner, :class)}##{colorize(name, :method)}#{colorize(args, :args)}"
+    end
+    alias :awesome_unboundmethod :awesome_method
+
+    # Format object instance.
+    #------------------------------------------------------------------------------
+    def awesome_instance(o)
+      "#{o.class}:0x%08x" % (o.__id__ * 2)
+    end
+
+    # Format object.methods array.
+    #------------------------------------------------------------------------------
+    def methods_array(a)
+      a.sort! { |x, y| x.to_s <=> y.to_s }                  # Can't simply a.sort! because of o.methods << [ :blah ]
+      object = a.instance_variable_get('@__awesome_methods__')
+      tuples = a.map do |name|
+        if name.is_a?(Symbol) || name.is_a?(String)         # Ignore garbage, ex. 42.methods << [ :blah ]
+          tuple = if object.respond_to?(name, true)         # Is this a regular method?
+            the_method = object.method(name) rescue nil     # Avoid potential ArgumentError if object#method is overridden.
+            if the_method && the_method.respond_to?(:arity) # Is this original object#method?
+              method_tuple(the_method)                      # Yes, we are good.
+            end
+          elsif object.respond_to?(:instance_method)              # Is this an unbound method?
+            method_tuple(object.instance_method(name)) rescue nil # Rescue to avoid NameError when the method is not
+          end                                                     # available (ex. File.lchmod on Ubuntu 12).
+        end
+        tuple || [ name.to_s, '(?)', '?' ]                  # Return WTF default if all the above fails.
+      end
+
+      width = (tuples.size - 1).to_s.size
+      name_width = tuples.map { |item| item[0].size }.max || 0
+      args_width = tuples.map { |item| item[1].size }.max || 0
+
+      data = tuples.inject([]) do |arr, item|
+        index = indent
+        index << "[#{arr.size.to_s.rjust(width)}]" if @options[:index]
+        indented do
+          arr << "#{index} #{colorize(item[0].rjust(name_width), :method)}#{colorize(item[1].ljust(args_width), :args)} #{colorize(item[2], :class)}"
+        end
+      end
+
+      "[\n" << data.join("\n") << "\n#{outdent}]"
+    end
+
+    # Return [ name, arguments, owner ] tuple for a given method.
+    #------------------------------------------------------------------------------
+    def method_tuple(method)
+      if method.respond_to?(:parameters) # Ruby 1.9.2+
+        # See http://ruby.runpaint.org/methods#method-objects-parameters
+        args = method.parameters.inject([]) do |arr, (type, name)|
+          name ||= (type == :block ? 'block' : "arg#{arr.size + 1}")
+          arr << case type
+            when :req        then name.to_s
+            when :opt, :rest then "*#{name}"
+            when :block      then "&#{name}"
+            else '?'
+          end
+        end
+      else # See http://ruby-doc.org/core/classes/Method.html#M001902
+        args = (1..method.arity.abs).map { |i| "arg#{i}" }
+        args[-1] = "*#{args[-1]}" if method.arity < 0
+      end
+
+      # method.to_s formats to handle:
+      #
+      # #<Method: Fixnum#zero?>
+      # #<Method: Fixnum(Integer)#years>
+      # #<Method: User(#<Module:0x00000103207c00>)#_username>
+      # #<Method: User(id: integer, username: string).table_name>
+      # #<Method: User(id: integer, username: string)(ActiveRecord::Base).current>
+      # #<UnboundMethod: Hello#world>
+      #
+      if method.to_s =~ /(Unbound)*Method: (.*)[#\.]/
+        unbound, klass = $1 && '(unbound)', $2
+        if klass && klass =~ /(\(\w+:\s.*?\))/  # Is this ActiveRecord-style class?
+          klass.sub!($1, '')                    # Yes, strip the fields leaving class name only.
+        end
+        owner = "#{klass}#{unbound}".gsub('(', ' (')
+      end
+
+      [ method.name.to_s, "(#{args.join(', ')})", owner.to_s ]
+    end
+
+    # Format hash keys as plain strings regardless of underlying data type.
+    #------------------------------------------------------------------------------
+    def plain_single_line
+      plain, multiline = @options[:plain], @options[:multiline]
+      @options[:plain], @options[:multiline] = true, false
+      yield
+    ensure
+      @options[:plain], @options[:multiline] = plain, multiline
+    end
+
+    # Utility methods.
+    #------------------------------------------------------------------------------
+    def align(value, width)
+      if @options[:multiline]
+        if @options[:indent] > 0
+          value.rjust(width)
+        elsif @options[:indent] == 0
+          indent + value.ljust(width)
+        else
+          indent[0, @indentation + @options[:indent]] + value.ljust(width)
+        end
+      else
+        value
+      end
+    end
+
+    def indented
+      @indentation += @options[:indent].abs
+      yield
+    ensure
+      @indentation -= @options[:indent].abs
+    end
+
+    def left_aligned
+      current, @options[:indent] = @options[:indent], 0
+      yield
+    ensure
+      @options[:indent] = current
+    end
+
+    def indent
+      ' ' * @indentation
+    end
+
+    def outdent
+      ' ' * (@indentation - @options[:indent].abs)
+    end
+
+    # To support limited output, for example:
+    #
+    # ap ('a'..'z').to_a, :limit => 3
+    # [
+    #     [ 0] "a",
+    #     [ 1] .. [24],
+    #     [25] "z"
+    # ]
+    #
+    # ap (1..100).to_a, :limit => true # Default limit is 7.
+    # [
+    #     [ 0] 1,
+    #     [ 1] 2,
+    #     [ 2] 3,
+    #     [ 3] .. [96],
+    #     [97] 98,
+    #     [98] 99,
+    #     [99] 100
+    # ]
+    #------------------------------------------------------------------------------
+    def should_be_limited?
+      @options[:limit] == true or (@options[:limit].is_a?(Fixnum) and @options[:limit] > 0)
+    end
+
+    def get_limit_size
+      @options[:limit] == true ? DEFAULT_LIMIT_SIZE : @options[:limit]
+    end
+
+    def limited(data, width, is_hash = false)
+      limit = get_limit_size
+      if data.length <= limit
+        data
+      else
+        # Calculate how many elements to be displayed above and below the separator.
+        head = limit / 2
+        tail = head - (limit - 1) % 2
+
+        # Add the proper elements to the temp array and format the separator.
+        temp = data[0, head] + [ nil ] + data[-tail, tail]
+
+        if is_hash
+          temp[head] = "#{indent}#{data[head].strip} .. #{data[data.length - tail - 1].strip}"
+        else
+          temp[head] = "#{indent}[#{head.to_s.rjust(width)}] .. [#{data.length - tail - 1}]"
+        end
+
+        temp
+      end
+    end
+  end
+end
diff --git a/lib/awesome_print/inspector.rb b/lib/awesome_print/inspector.rb
new file mode 100755
index 0000000..0893a90
--- /dev/null
+++ b/lib/awesome_print/inspector.rb
@@ -0,0 +1,171 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+module AwesomePrint
+
+  class << self # Class accessors for custom defaults.
+    attr_accessor :defaults, :force_colors
+
+    # Class accessor to force colorized output (ex. forked subprocess where TERM
+    # might be dumb).
+    #------------------------------------------------------------------------------
+    def force_colors!(value = true)
+      @force_colors = value
+    end
+
+    def console?
+      !!(defined?(IRB) || defined?(Pry))
+    end
+
+    def rails_console?
+      console? && !!(defined?(Rails::Console) || ENV["RAILS_ENV"])
+    end
+
+    def irb!
+      return unless defined?(IRB)
+      unless IRB.version.include?("DietRB")
+        IRB::Irb.class_eval do
+          def output_value
+            ap @context.last_value
+          end
+        end
+      else # MacRuby
+        IRB.formatter = Class.new(IRB::Formatter) do
+          def inspect_object(object)
+            object.ai
+          end
+        end.new
+      end
+    end
+
+    def pry!
+      if defined?(Pry)
+        Pry.print = proc { |output, value| output.puts value.ai }
+      end
+    end
+  end
+
+  class Inspector
+    attr_accessor :options
+
+    AP = :__awesome_print__
+
+    def initialize(options = {})
+      @options = { 
+        :indent     => 4,      # Indent using 4 spaces.
+        :index      => true,   # Display array indices.
+        :html       => false,  # Use ANSI color codes rather than HTML.
+        :multiline  => true,   # Display in multiple lines.
+        :plain      => false,  # Use colors.
+        :raw        => false,  # Do not recursively format object instance variables.
+        :sort_keys  => false,  # Do not sort hash keys.
+        :limit      => false,  # Limit large output for arrays and hashes. Set to a boolean or integer.
+        :color => { 
+          :args       => :pale,
+          :array      => :white,
+          :bigdecimal => :blue,
+          :class      => :yellow,
+          :date       => :greenish,
+          :falseclass => :red,
+          :fixnum     => :blue,
+          :float      => :blue,
+          :hash       => :pale,
+          :keyword    => :cyan,
+          :method     => :purpleish,
+          :nilclass   => :red,
+          :rational   => :blue,
+          :string     => :yellowish,
+          :struct     => :pale,
+          :symbol     => :cyanish,
+          :time       => :greenish,
+          :trueclass  => :green,
+          :variable   => :cyanish
+        }
+      }
+
+      # Merge custom defaults and let explicit options parameter override them.
+      merge_custom_defaults!
+      merge_options!(options)
+
+      @formatter = AwesomePrint::Formatter.new(self)
+      Thread.current[AP] ||= []
+    end
+  
+    # Dispatcher that detects data nesting and invokes object-aware formatter.
+    #------------------------------------------------------------------------------
+    def awesome(object)
+      if Thread.current[AP].include?(object.object_id)
+        nested(object)
+      else
+        begin
+          Thread.current[AP] << object.object_id
+          unnested(object)
+        ensure
+          Thread.current[AP].pop
+        end
+      end
+    end
+
+    # Return true if we are to colorize the output.
+    #------------------------------------------------------------------------------
+    def colorize?
+      AwesomePrint.force_colors ||= false
+      AwesomePrint.force_colors || (STDOUT.tty? && ((ENV['TERM'] && ENV['TERM'] != 'dumb') || ENV['ANSICON']))
+    end
+
+    private
+
+    # Format nested data, for example:
+    #   arr = [1, 2]; arr << arr
+    #   => [1,2, [...]]
+    #   hash = { :a => 1 }; hash[:b] = hash
+    #   => { :a => 1, :b => {...} }
+    #------------------------------------------------------------------------------
+    def nested(object)
+      case printable(object)
+        when :array  then @formatter.colorize("[...]", :array)
+        when :hash   then @formatter.colorize("{...}", :hash)
+        when :struct then @formatter.colorize("{...}", :struct)
+        else @formatter.colorize("...#{object.class}...", :class)
+      end
+    end
+
+    #------------------------------------------------------------------------------
+    def unnested(object)
+      @formatter.format(object, printable(object))
+    end
+
+    # Turn class name into symbol, ex: Hello::World => :hello_world. Classes that
+    # inherit from Array, Hash, File, Dir, and Struct are treated as the base class.
+    #------------------------------------------------------------------------------
+    def printable(object)
+      case object
+      when Array  then :array
+      when Hash   then :hash
+      when File   then :file
+      when Dir    then :dir
+      when Struct then :struct
+      else object.class.to_s.gsub(/:+/, "_").downcase.to_sym
+      end
+    end
+
+    # Update @options by first merging the :color hash and then the remaining keys.
+    #------------------------------------------------------------------------------
+    def merge_options!(options = {})
+      @options[:color].merge!(options.delete(:color) || {})
+      @options.merge!(options)
+    end
+
+    # Load ~/.aprc file with custom defaults that override default options.
+    #------------------------------------------------------------------------------
+    def merge_custom_defaults!
+      dotfile = File.join(ENV["HOME"], ".aprc")
+      load dotfile if File.readable?(dotfile)
+      merge_options!(AwesomePrint.defaults) if AwesomePrint.defaults.is_a?(Hash)
+    rescue => e
+      $stderr.puts "Could not load #{dotfile}: #{e}"
+    end
+  end
+end
diff --git a/lib/awesome_print/version.rb b/lib/awesome_print/version.rb
new file mode 100644
index 0000000..2bca309
--- /dev/null
+++ b/lib/awesome_print/version.rb
@@ -0,0 +1,10 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+module AwesomePrint
+  def self.version
+    "1.2.0"
+  end
+end
diff --git a/metadata.yml b/metadata.yml
new file mode 100644
index 0000000..9900a41
--- /dev/null
+++ b/metadata.yml
@@ -0,0 +1,117 @@
+--- !ruby/object:Gem::Specification
+name: awesome_print
+version: !ruby/object:Gem::Version
+  version: 1.2.0
+  prerelease: 
+platform: ruby
+authors:
+- Michael Dvorkin
+autorequire: 
+bindir: bin
+cert_chain: []
+date: 2013-09-24 00:00:00.000000000 Z
+dependencies:
+- !ruby/object:Gem::Dependency
+  name: rspec
+  requirement: !ruby/object:Gem::Requirement
+    none: false
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: 2.6.0
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    none: false
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: 2.6.0
+- !ruby/object:Gem::Dependency
+  name: fakefs
+  requirement: !ruby/object:Gem::Requirement
+    none: false
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: 0.2.1
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    none: false
+    requirements:
+    - - ! '>='
+      - !ruby/object:Gem::Version
+        version: 0.2.1
+description: ! 'Great Ruby dubugging companion: pretty print Ruby objects to visualize
+  their structure. Supports custom object formatting via plugins'
+email: mike at dvorkin.net
+executables: []
+extensions: []
+extra_rdoc_files: []
+files:
+- CHANGELOG
+- Gemfile
+- Gemfile.lock
+- LICENSE
+- Rakefile
+- README.md
+- lib/ap.rb
+- lib/awesome_print/core_ext/array.rb
+- lib/awesome_print/core_ext/class.rb
+- lib/awesome_print/core_ext/kernel.rb
+- lib/awesome_print/core_ext/logger.rb
+- lib/awesome_print/core_ext/method.rb
+- lib/awesome_print/core_ext/object.rb
+- lib/awesome_print/core_ext/string.rb
+- lib/awesome_print/ext/action_view.rb
+- lib/awesome_print/ext/active_record.rb
+- lib/awesome_print/ext/active_support.rb
+- lib/awesome_print/ext/mongo_mapper.rb
+- lib/awesome_print/ext/mongoid.rb
+- lib/awesome_print/ext/no_brainer.rb
+- lib/awesome_print/ext/nokogiri.rb
+- lib/awesome_print/ext/ripple.rb
+- lib/awesome_print/ext/sequel.rb
+- lib/awesome_print/formatter.rb
+- lib/awesome_print/inspector.rb
+- lib/awesome_print/version.rb
+- lib/awesome_print.rb
+- spec/colors_spec.rb
+- spec/formats_spec.rb
+- spec/methods_spec.rb
+- spec/misc_spec.rb
+- spec/objects_spec.rb
+- spec/spec_helper.rb
+- .gitignore
+homepage: http://github.com/michaeldv/awesome_print
+licenses: []
+post_install_message: 
+rdoc_options: []
+require_paths:
+- lib
+required_ruby_version: !ruby/object:Gem::Requirement
+  none: false
+  requirements:
+  - - ! '>='
+    - !ruby/object:Gem::Version
+      version: '0'
+required_rubygems_version: !ruby/object:Gem::Requirement
+  none: false
+  requirements:
+  - - ! '>='
+    - !ruby/object:Gem::Version
+      version: '0'
+requirements: []
+rubyforge_project: awesome_print
+rubygems_version: 1.8.24
+signing_key: 
+specification_version: 3
+summary: Pretty print Ruby objects with proper indentation and colors
+test_files:
+- spec/colors_spec.rb
+- spec/formats_spec.rb
+- spec/methods_spec.rb
+- spec/misc_spec.rb
+- spec/objects_spec.rb
+- spec/spec_helper.rb
diff --git a/spec/colors_spec.rb b/spec/colors_spec.rb
new file mode 100644
index 0000000..17f2e63
--- /dev/null
+++ b/spec/colors_spec.rb
@@ -0,0 +1,106 @@
+require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
+
+describe "AwesomePrint" do
+  def stub_tty!(output = true, stream = STDOUT)
+    if output
+      stream.instance_eval { def tty?;  true; end }
+    else
+      stream.instance_eval { def tty?; false; end }
+    end
+  end
+
+  before do
+    stub_dotfile!
+  end
+
+  describe "colorization" do
+    PLAIN = '[ 1, :two, "three", [ nil, [ true, false ] ] ]'
+    COLORIZED = "[ \e[1;34m1\e[0m, \e[0;36m:two\e[0m, \e[0;33m\"three\"\e[0m, [ \e[1;31mnil\e[0m, [ \e[1;32mtrue\e[0m, \e[1;31mfalse\e[0m ] ] ]"
+
+    before do
+      ENV['TERM'] = "xterm-colors"
+      ENV.delete('ANSICON')
+      @arr = [ 1, :two, "three", [ nil, [ true, false] ] ]
+    end
+
+    describe "default settings (no forced colors)" do
+      before do
+        AwesomePrint.force_colors! false
+      end
+
+      it "colorizes tty processes by default" do
+        stub_tty!
+        @arr.ai(:multiline => false).should == COLORIZED
+      end
+
+      it "colorizes processes with ENV['ANSICON'] by default" do
+        begin
+          stub_tty!
+          term, ENV['ANSICON'] = ENV['ANSICON'], "1"
+          @arr.ai(:multiline => false).should == COLORIZED
+        ensure
+          ENV['ANSICON'] = term
+        end
+      end
+
+      it "does not colorize tty processes running in dumb terminals by default" do
+        begin
+          stub_tty!
+          term, ENV['TERM'] = ENV['TERM'], "dumb"
+          @arr.ai(:multiline => false).should == PLAIN
+        ensure
+          ENV['TERM'] = term
+        end
+      end
+
+      it "does not colorize subprocesses by default" do
+        begin
+          stub_tty! false
+          @arr.ai(:multiline => false).should == PLAIN
+        ensure
+          stub_tty!
+        end
+      end
+    end
+
+    describe "forced colors override" do
+      before do
+        AwesomePrint.force_colors!
+      end
+      
+      it "still colorizes tty processes" do
+        stub_tty!
+        @arr.ai(:multiline => false).should == COLORIZED
+      end
+
+      it "colorizes processes with ENV['ANSICON'] set to 0" do
+        begin
+          stub_tty!
+          term, ENV['ANSICON'] = ENV['ANSICON'], "1"
+          @arr.ai(:multiline => false).should == COLORIZED
+        ensure
+          ENV['ANSICON'] = term
+        end
+      end
+      
+      it "colorizes dumb terminals" do
+        begin
+          stub_tty!
+          term, ENV['TERM'] = ENV['TERM'], "dumb"
+          @arr.ai(:multiline => false).should == COLORIZED
+        ensure
+          ENV['TERM'] = term
+        end
+      end
+
+      it "colorizes subprocess" do
+        begin
+          stub_tty! false
+          @arr.ai(:multiline => false).should == COLORIZED
+        ensure
+          stub_tty!
+        end
+      end
+    end
+  end
+end
diff --git a/spec/formats_spec.rb b/spec/formats_spec.rb
new file mode 100644
index 0000000..b577ede
--- /dev/null
+++ b/spec/formats_spec.rb
@@ -0,0 +1,712 @@
+require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
+require "bigdecimal"
+require "rational"
+require "set"
+
+describe "AwesomePrint" do
+  before do
+    stub_dotfile!
+  end
+
+  describe "Array" do
+    before do
+      @arr = [ 1, :two, "three", [ nil, [ true, false] ] ]
+    end
+
+    it "empty array" do
+      [].ai.should == "[]"
+    end
+
+    it "plain multiline" do
+      @arr.ai(:plain => true).should == <<-EOS.strip
+[
+    [0] 1,
+    [1] :two,
+    [2] "three",
+    [3] [
+        [0] nil,
+        [1] [
+            [0] true,
+            [1] false
+        ]
+    ]
+]
+EOS
+      end
+
+    it "plain multiline without index" do
+      @arr.ai(:plain => true, :index => false).should == <<-EOS.strip
+[
+    1,
+    :two,
+    "three",
+    [
+        nil,
+        [
+            true,
+            false
+        ]
+    ]
+]
+EOS
+      end
+
+    it "plain multiline indented" do
+      @arr.ai(:plain => true, :indent => 2).should == <<-EOS.strip
+[
+  [0] 1,
+  [1] :two,
+  [2] "three",
+  [3] [
+    [0] nil,
+    [1] [
+      [0] true,
+      [1] false
+    ]
+  ]
+]
+EOS
+    end
+
+    it "plain multiline indented without index" do
+      @arr.ai(:plain => true, :indent => 2, :index => false).should == <<-EOS.strip
+[
+  1,
+  :two,
+  "three",
+  [
+    nil,
+    [
+      true,
+      false
+    ]
+  ]
+]
+EOS
+    end
+
+    it "plain single line" do
+      @arr.ai(:plain => true, :multiline => false).should == '[ 1, :two, "three", [ nil, [ true, false ] ] ]'
+    end
+
+    it "colored multiline (default)" do
+      @arr.ai.should == <<-EOS.strip
+[
+    \e[1;37m[0] \e[0m\e[1;34m1\e[0m,
+    \e[1;37m[1] \e[0m\e[0;36m:two\e[0m,
+    \e[1;37m[2] \e[0m\e[0;33m\"three\"\e[0m,
+    \e[1;37m[3] \e[0m[
+        \e[1;37m[0] \e[0m\e[1;31mnil\e[0m,
+        \e[1;37m[1] \e[0m[
+            \e[1;37m[0] \e[0m\e[1;32mtrue\e[0m,
+            \e[1;37m[1] \e[0m\e[1;31mfalse\e[0m
+        ]
+    ]
+]
+EOS
+      end
+
+    it "colored multiline indented" do
+      @arr.ai(:indent => 8).should == <<-EOS.strip
+[
+        \e[1;37m[0] \e[0m\e[1;34m1\e[0m,
+        \e[1;37m[1] \e[0m\e[0;36m:two\e[0m,
+        \e[1;37m[2] \e[0m\e[0;33m\"three\"\e[0m,
+        \e[1;37m[3] \e[0m[
+                \e[1;37m[0] \e[0m\e[1;31mnil\e[0m,
+                \e[1;37m[1] \e[0m[
+                        \e[1;37m[0] \e[0m\e[1;32mtrue\e[0m,
+                        \e[1;37m[1] \e[0m\e[1;31mfalse\e[0m
+                ]
+        ]
+]
+EOS
+    end
+
+    it "colored single line" do
+      @arr.ai(:multiline => false).should == "[ \e[1;34m1\e[0m, \e[0;36m:two\e[0m, \e[0;33m\"three\"\e[0m, [ \e[1;31mnil\e[0m, [ \e[1;32mtrue\e[0m, \e[1;31mfalse\e[0m ] ] ]"
+    end
+  end
+
+  #------------------------------------------------------------------------------
+  describe "Nested Array" do
+    before do
+      @arr = [ 1, 2 ]
+      @arr << @arr
+    end
+
+    it "plain multiline" do
+      @arr.ai(:plain => true).should == <<-EOS.strip
+[
+    [0] 1,
+    [1] 2,
+    [2] [...]
+]
+EOS
+    end
+
+    it "plain multiline without index" do
+      @arr.ai(:plain => true, :index => false).should == <<-EOS.strip
+[
+    1,
+    2,
+    [...]
+]
+EOS
+    end
+
+    it "plain single line" do
+      @arr.ai(:plain => true, :multiline => false).should == "[ 1, 2, [...] ]"
+    end
+  end
+
+  #------------------------------------------------------------------------------
+  describe "Limited Output Array" do
+    before(:each) do
+      @arr = (1..1000).to_a
+    end
+
+    it "plain limited output large" do
+      @arr.ai(:plain => true, :limit => true).should == <<-EOS.strip
+[
+    [  0] 1,
+    [  1] 2,
+    [  2] 3,
+    [  3] .. [996],
+    [997] 998,
+    [998] 999,
+    [999] 1000
+]
+EOS
+    end
+
+    it "plain limited output small" do
+      @arr = @arr[0..3]
+      @arr.ai(:plain => true, :limit => true).should == <<-EOS.strip
+[
+    [0] 1,
+    [1] 2,
+    [2] 3,
+    [3] 4
+]
+EOS
+    end
+
+    it "plain limited output with 10 lines" do
+      @arr.ai(:plain => true, :limit => 10).should == <<-EOS.strip
+[
+    [  0] 1,
+    [  1] 2,
+    [  2] 3,
+    [  3] 4,
+    [  4] 5,
+    [  5] .. [995],
+    [996] 997,
+    [997] 998,
+    [998] 999,
+    [999] 1000
+]
+EOS
+    end
+
+    it "plain limited output with 11 lines" do
+      @arr.ai(:plain => true, :limit => 11).should == <<-EOS.strip
+[
+    [  0] 1,
+    [  1] 2,
+    [  2] 3,
+    [  3] 4,
+    [  4] 5,
+    [  5] .. [994],
+    [995] 996,
+    [996] 997,
+    [997] 998,
+    [998] 999,
+    [999] 1000
+]
+EOS
+    end
+  end
+
+  #------------------------------------------------------------------------------
+  describe "Limited Output Hash" do
+    before(:each) do
+      @hash = ("a".."z").inject({}) { |h, v| h.merge({ v => v.to_sym }) }
+    end
+
+    it "plain limited output" do
+      @hash.ai(:sort_keys => true, :plain => true, :limit => true).should == <<-EOS.strip
+{
+    "a" => :a,
+    "b" => :b,
+    "c" => :c,
+    "d" => :d .. "w" => :w,
+    "x" => :x,
+    "y" => :y,
+    "z" => :z
+}
+EOS
+    end
+  end
+
+  #------------------------------------------------------------------------------
+  describe "Hash" do
+    before do
+      @hash = { 1 => { :sym => { "str" => { [1, 2, 3] => { { :k => :v } => Hash } } } } }
+    end
+    
+    it "empty hash" do
+      {}.ai.should == "{}"
+    end
+    
+    it "plain multiline" do
+      @hash.ai(:plain => true).should == <<-EOS.strip
+{
+    1 => {
+        :sym => {
+            "str" => {
+                [ 1, 2, 3 ] => {
+                    { :k => :v } => Hash < Object
+                }
+            }
+        }
+    }
+}
+EOS
+    end
+
+    it "plain multiline indented" do
+      @hash.ai(:plain => true, :indent => 1).should == <<-EOS.strip
+{
+ 1 => {
+  :sym => {
+   "str" => {
+    [ 1, 2, 3 ] => {
+     { :k => :v } => Hash < Object
+    }
+   }
+  }
+ }
+}
+EOS
+    end
+
+    it "plain single line" do
+      @hash.ai(:plain => true, :multiline => false).should == '{ 1 => { :sym => { "str" => { [ 1, 2, 3 ] => { { :k => :v } => Hash < Object } } } } }'
+    end
+
+    it "colored multiline (default)" do
+      @hash.ai.should == <<-EOS.strip
+{
+    1\e[0;37m => \e[0m{
+        :sym\e[0;37m => \e[0m{
+            \"str\"\e[0;37m => \e[0m{
+                [ 1, 2, 3 ]\e[0;37m => \e[0m{
+                    { :k => :v }\e[0;37m => \e[0m\e[1;33mHash < Object\e[0m
+                }
+            }
+        }
+    }
+}
+EOS
+    end
+
+    it "colored multiline indented" do
+      @hash.ai(:indent => 2).should == <<-EOS.strip
+{
+  1\e[0;37m => \e[0m{
+    :sym\e[0;37m => \e[0m{
+      \"str\"\e[0;37m => \e[0m{
+        [ 1, 2, 3 ]\e[0;37m => \e[0m{
+          { :k => :v }\e[0;37m => \e[0m\e[1;33mHash < Object\e[0m
+        }
+      }
+    }
+  }
+}
+EOS
+    end
+
+    it "colored single line" do
+      @hash.ai(:multiline => false).should == "{ 1\e[0;37m => \e[0m{ :sym\e[0;37m => \e[0m{ \"str\"\e[0;37m => \e[0m{ [ 1, 2, 3 ]\e[0;37m => \e[0m{ { :k => :v }\e[0;37m => \e[0m\e[1;33mHash < Object\e[0m } } } } }"
+    end
+
+  end
+
+  #------------------------------------------------------------------------------
+  describe "Nested Hash" do
+    before do
+      @hash = {}
+      @hash[:a] = @hash
+    end
+
+    it "plain multiline" do
+      @hash.ai(:plain => true).should == <<-EOS.strip
+{
+    :a => {...}
+}
+EOS
+    end
+
+    it "plain single line" do
+      @hash.ai(:plain => true, :multiline => false).should == '{ :a => {...} }'
+    end
+  end
+
+  #------------------------------------------------------------------------------
+  describe "Hash with several keys" do
+    before do
+      @hash = {"b" => "b", :a => "a", :z => "z", "alpha" => "alpha"}
+    end
+
+    it "plain multiline" do
+      out = @hash.ai(:plain => true)
+      if RUBY_VERSION.to_f < 1.9 # Order of @hash keys is not guaranteed.
+        out.should =~ /^\{[^\}]+\}/m
+        out.should =~ /        "b" => "b",?/
+        out.should =~ /         :a => "a",?/
+        out.should =~ /         :z => "z",?/
+        out.should =~ /    "alpha" => "alpha",?$/
+      else
+        out.should == <<-EOS.strip
+{
+        "b" => "b",
+         :a => "a",
+         :z => "z",
+    "alpha" => "alpha"
+}
+EOS
+      end
+    end
+    
+    it "plain multiline with sorted keys" do
+      @hash.ai(:plain => true, :sort_keys => true).should == <<-EOS.strip
+{
+         :a => "a",
+    "alpha" => "alpha",
+        "b" => "b",
+         :z => "z"
+}
+EOS
+    end
+
+  end
+
+  #------------------------------------------------------------------------------
+  describe "Negative options[:indent]" do
+    #
+    # With Ruby < 1.9 the order of hash keys is not defined so we can't
+    # reliably compare the output string.
+    #
+    it "hash keys must be left aligned" do
+      hash = { [0, 0, 255] => :yellow, :red => "rgb(255, 0, 0)", "magenta" => "rgb(255, 0, 255)" }
+      out = hash.ai(:plain => true, :indent => -4, :sort_keys => true)
+      out.should == <<-EOS.strip
+{
+    [ 0, 0, 255 ] => :yellow,
+    "magenta"     => "rgb(255, 0, 255)",
+    :red          => "rgb(255, 0, 0)"
+}
+EOS
+    end
+
+    it "nested hash keys should be indented (array of hashes)" do
+      arr = [ { :a => 1, :bb => 22, :ccc => 333}, { 1 => :a, 22 => :bb, 333 => :ccc} ]
+      out = arr.ai(:plain => true, :indent => -4, :sort_keys => true)
+      out.should == <<-EOS.strip
+[
+    [0] {
+        :a   => 1,
+        :bb  => 22,
+        :ccc => 333
+    },
+    [1] {
+        1   => :a,
+        22  => :bb,
+        333 => :ccc
+    }
+]
+EOS
+    end
+
+    it "nested hash keys should be indented (hash of hashes)" do
+      arr = { :first => { :a => 1, :bb => 22, :ccc => 333}, :second => { 1 => :a, 22 => :bb, 333 => :ccc} }
+      out = arr.ai(:plain => true, :indent => -4, :sort_keys => true)
+      out.should == <<-EOS.strip
+{
+    :first  => {
+        :a   => 1,
+        :bb  => 22,
+        :ccc => 333
+    },
+    :second => {
+        1   => :a,
+        22  => :bb,
+        333 => :ccc
+    }
+}
+EOS
+    end
+  end
+
+  #------------------------------------------------------------------------------
+  describe "Class" do
+    it "shoud show superclass (plain)" do
+      self.class.ai(:plain => true).should == "#{self.class} < #{self.class.superclass}"
+    end
+
+    it "shoud show superclass (color)" do
+      self.class.ai.should == "#{self.class} < #{self.class.superclass}".yellow
+    end
+  end
+
+  #------------------------------------------------------------------------------
+  describe "File" do
+    it "should display a file (plain)" do
+      File.open(__FILE__, "r") do |f|
+        f.ai(:plain => true).should == "#{f.inspect}\n" << `ls -alF #{f.path}`.chop
+      end
+    end
+  end
+
+  #------------------------------------------------------------------------------
+  describe "Dir" do
+    it "should display a direcory (plain)" do
+      Dir.open(File.dirname(__FILE__)) do |d|
+        d.ai(:plain => true).should == "#{d.inspect}\n" << `ls -alF #{d.path}`.chop
+      end
+    end
+  end
+
+  #------------------------------------------------------------------------------
+  describe "BigDecimal and Rational" do
+    it "should present BigDecimal object with arbitrary precision" do
+      big = BigDecimal("201020102010201020102010201020102010.4")
+      big.ai(:plain => true).should == "201020102010201020102010201020102010.4"
+    end
+
+    it "should present Rational object with arbitrary precision" do
+      rat = Rational(201020102010201020102010201020102010, 2)
+      out = rat.ai(:plain => true)
+      #
+      # Ruby 1.9 slightly changed the format of Rational#to_s, see
+      # http://techtime.getharvest.com/blog/harvest-is-now-on-ruby-1-dot-9-3 and
+      # http://www.ruby-forum.com/topic/189397
+      #
+      if RUBY_VERSION < "1.9"
+        out.should == "100510051005100510051005100510051005"
+      else
+        out.should == "100510051005100510051005100510051005/1"
+      end
+    end
+  end
+
+  #------------------------------------------------------------------------------
+  describe "Utility methods" do
+    it "should merge options" do
+      ap = AwesomePrint::Inspector.new
+      ap.send(:merge_options!, { :color => { :array => :black }, :indent => 0 })
+      options = ap.instance_variable_get("@options")
+      options[:color][:array].should == :black
+      options[:indent].should == 0
+    end
+  end
+
+  #------------------------------------------------------------------------------
+  describe "Set" do
+    before do
+      @arr = [1, :two, "three" ]
+      @set = Set.new(@arr)
+    end
+
+    it "empty set" do
+      Set.new.ai.should == [].ai
+    end
+
+    if RUBY_VERSION > "1.9"
+      it "plain multiline" do
+        @set.ai(:plain => true).should == @arr.ai(:plain => true)
+      end
+
+      it "plain multiline indented" do
+        @set.ai(:plain => true, :indent => 1).should == @arr.ai(:plain => true, :indent => 1)
+      end
+
+      it "plain single line" do
+        @set.ai(:plain => true, :multiline => false).should == @arr.ai(:plain => true, :multiline => false)
+      end
+
+      it "colored multiline (default)" do
+        @set.ai.should == @arr.ai
+      end
+    else # Prior to Ruby 1.9 the order of set values is unpredicatble.
+      it "plain multiline" do
+        @set.sort_by{ |x| x.to_s }.ai(:plain => true).should == @arr.sort_by{ |x| x.to_s }.ai(:plain => true)
+      end
+
+      it "plain multiline indented" do
+        @set.sort_by{ |x| x.to_s }.ai(:plain => true, :indent => 1).should == @arr.sort_by{ |x| x.to_s }.ai(:plain => true, :indent => 1)
+      end
+
+      it "plain single line" do
+        @set.sort_by{ |x| x.to_s }.ai(:plain => true, :multiline => false).should == @arr.sort_by{ |x| x.to_s }.ai(:plain => true, :multiline => false)
+      end
+
+      it "colored multiline (default)" do
+        @set.sort_by{ |x| x.to_s }.ai.should == @arr.sort_by{ |x| x.to_s }.ai
+      end
+    end
+  end
+
+  #------------------------------------------------------------------------------
+  describe "Struct" do
+    before do
+      @struct = unless defined?(Struct::SimpleStruct)
+        Struct.new("SimpleStruct", :name, :address).new
+      else
+        Struct::SimpleStruct.new
+      end
+      @struct.name = "Herman Munster"
+      @struct.address = "1313 Mockingbird Lane"
+    end
+    
+    it "empty struct" do
+      Struct.new("EmptyStruct").ai.should ==  "\e[1;33mStruct::EmptyStruct < Struct\e[0m"
+    end
+    
+    it "plain multiline" do
+      s1 = <<-EOS.strip
+{
+    :address => "1313 Mockingbird Lane",
+       :name => "Herman Munster"
+}
+EOS
+      s2 = <<-EOS.strip
+{
+       :name => "Herman Munster",
+    :address => "1313 Mockingbird Lane"
+}
+EOS
+      @struct.ai(:plain => true).should satisfy { |match| match == s1 || match == s2 }
+    end
+
+    it "plain multiline indented" do
+      s1 = <<-EOS.strip
+{
+ :address => "1313 Mockingbird Lane",
+    :name => "Herman Munster"
+}
+EOS
+      s2 = <<-EOS.strip
+{
+    :name => "Herman Munster",
+ :address => "1313 Mockingbird Lane"
+}
+EOS
+      @struct.ai(:plain => true, :indent => 1).should satisfy { |match| match == s1 || match == s2 }
+    end
+
+    it "plain single line" do
+      s1 = "{ :address => \"1313 Mockingbird Lane\", :name => \"Herman Munster\" }"
+      s2 = "{ :name => \"Herman Munster\", :address => \"1313 Mockingbird Lane\" }"
+      @struct.ai(:plain => true, :multiline => false).should satisfy { |match| match == s1 || match == s2 }
+    end
+
+    it "colored multiline (default)" do
+      s1 = <<-EOS.strip
+{
+    :address\e[0;37m => \e[0m\e[0;33m\"1313 Mockingbird Lane\"\e[0m,
+       :name\e[0;37m => \e[0m\e[0;33m\"Herman Munster\"\e[0m
+}
+EOS
+      s2 = <<-EOS.strip
+{
+       :name\e[0;37m => \e[0m\e[0;33m\"Herman Munster\"\e[0m,
+    :address\e[0;37m => \e[0m\e[0;33m\"1313 Mockingbird Lane\"\e[0m
+}
+EOS
+      @struct.ai.should satisfy { |match| match == s1 || match == s2 }
+    end
+  end
+
+  #------------------------------------------------------------------------------
+  describe "Inherited from standard Ruby classes" do
+    after do
+      Object.instance_eval{ remove_const :My } if defined?(My)
+    end
+
+    it "inherited from Array should be displayed as Array" do
+      class My < Array; end
+
+      my = My.new([ 1, :two, "three", [ nil, [ true, false ] ] ])
+      my.ai(:plain => true).should == <<-EOS.strip
+[
+    [0] 1,
+    [1] :two,
+    [2] "three",
+    [3] [
+        [0] nil,
+        [1] [
+            [0] true,
+            [1] false
+        ]
+    ]
+]
+EOS
+    end
+
+    it "inherited from Hash should be displayed as Hash" do
+      class My < Hash; end
+
+      my = My[ { 1 => { :sym => { "str" => { [1, 2, 3] => { { :k => :v } => Hash } } } } } ]
+      my.ai(:plain => true).should == <<-EOS.strip
+{
+    1 => {
+        :sym => {
+            "str" => {
+                [ 1, 2, 3 ] => {
+                    { :k => :v } => Hash < Object
+                }
+            }
+        }
+    }
+}
+EOS
+    end
+
+    it "inherited from File should be displayed as File" do
+      class My < File; end
+
+      my = File.new('/dev/null') rescue File.new('nul')
+      my.ai(:plain => true).should == "#{my.inspect}\n" << `ls -alF #{my.path}`.chop
+    end
+
+    it "inherited from Dir should be displayed as Dir" do
+      class My < Dir; end
+
+      require 'tmpdir'
+      my = My.new(Dir.tmpdir)
+      my.ai(:plain => true).should == "#{my.inspect}\n" << `ls -alF #{my.path}`.chop
+    end
+
+    it "should handle a class that defines its own #send method" do
+      class My
+        def send(arg1, arg2, arg3); end
+      end
+
+      my = My.new
+      my.methods.ai(:plain => true).should_not raise_error(ArgumentError)
+    end
+
+    it "should handle a class defines its own #method method (ex. request.method)" do
+      class My
+        def method
+          'POST'
+        end
+      end
+
+      my = My.new
+      my.methods.ai(:plain => true).should_not raise_error(ArgumentError)
+    end
+  end
+end
diff --git a/spec/methods_spec.rb b/spec/methods_spec.rb
new file mode 100644
index 0000000..22d5ca3
--- /dev/null
+++ b/spec/methods_spec.rb
@@ -0,0 +1,459 @@
+require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
+
+describe "Single method" do
+  before do
+    stub_dotfile!
+  end
+
+  after do
+    Object.instance_eval{ remove_const :Hello } if defined?(Hello)
+  end
+
+  it "plain: should handle a method with no arguments" do
+    method = ''.method(:upcase)
+    method.ai(:plain => true).should == 'String#upcase()'
+  end
+
+  it "color: should handle a method with no arguments" do
+    method = ''.method(:upcase)
+    method.ai.should == "\e[1;33mString\e[0m#\e[0;35mupcase\e[0m\e[0;37m()\e[0m"
+  end
+
+  it "plain: should handle a method with one argument" do
+    method = ''.method(:include?)
+    method.ai(:plain => true).should == 'String#include?(arg1)'
+  end
+
+  it "color: should handle a method with one argument" do
+    method = ''.method(:include?)
+    method.ai.should == "\e[1;33mString\e[0m#\e[0;35minclude?\e[0m\e[0;37m(arg1)\e[0m"
+  end
+
+  it "plain: should handle a method with two arguments" do
+    method = ''.method(:tr)
+    method.ai(:plain => true).should == 'String#tr(arg1, arg2)'
+  end
+
+  it "color: should handle a method with two arguments" do
+    method = ''.method(:tr)
+    method.ai.should == "\e[1;33mString\e[0m#\e[0;35mtr\e[0m\e[0;37m(arg1, arg2)\e[0m"
+  end
+
+  it "plain: should handle a method with multiple arguments" do
+    method = ''.method(:split)
+    method.ai(:plain => true).should == 'String#split(*arg1)'
+  end
+
+  it "color: should handle a method with multiple arguments" do
+    method = ''.method(:split)
+    method.ai.should == "\e[1;33mString\e[0m#\e[0;35msplit\e[0m\e[0;37m(*arg1)\e[0m"
+  end
+
+  it "plain: should handle a method defined in mixin" do
+    method = ''.method(:is_a?)
+    method.ai(:plain => true).should == 'String (Kernel)#is_a?(arg1)'
+  end
+
+  it "color: should handle a method defined in mixin" do
+    method = ''.method(:is_a?)
+    method.ai.should == "\e[1;33mString (Kernel)\e[0m#\e[0;35mis_a?\e[0m\e[0;37m(arg1)\e[0m"
+  end
+
+  it "plain: should handle an unbound method" do
+    class Hello
+      def world; end
+    end
+    method = Hello.instance_method(:world)
+    method.ai(:plain => true).should == 'Hello (unbound)#world()'
+  end
+
+  it "color: should handle an unbound method" do
+    class Hello
+      def world(a,b); end
+    end
+    method = Hello.instance_method(:world)
+    if RUBY_VERSION < '1.9.2'
+      method.ai.should == "\e[1;33mHello (unbound)\e[0m#\e[0;35mworld\e[0m\e[0;37m(arg1, arg2)\e[0m"
+    else
+      method.ai.should == "\e[1;33mHello (unbound)\e[0m#\e[0;35mworld\e[0m\e[0;37m(a, b)\e[0m"
+    end
+  end
+end
+
+describe "Object methods" do
+  before do
+    stub_dotfile!
+  end
+
+  after do
+    Object.instance_eval{ remove_const :Hello } if defined?(Hello)
+  end
+
+  describe "object.methods" do
+    it "index: should handle object.methods" do
+      out = nil.methods.ai(:plain => true).split("\n").grep(/is_a\?/).first
+      out.should =~ /^\s+\[\s*\d+\]\s+is_a\?\(arg1\)\s+NilClass \(Kernel\)$/
+    end
+
+    it "no index: should handle object.methods" do
+      out = nil.methods.ai(:plain => true, :index => false).split("\n").grep(/is_a\?/).first
+      out.should =~ /^\s+is_a\?\(arg1\)\s+NilClass \(Kernel\)$/
+    end
+  end
+
+  describe "object.public_methods" do
+    it "index: should handle object.public_methods" do
+      out = nil.public_methods.ai(:plain => true).split("\n").grep(/is_a\?/).first
+      out.should =~ /^\s+\[\s*\d+\]\s+is_a\?\(arg1\)\s+NilClass \(Kernel\)$/
+    end
+
+    it "no index: should handle object.public_methods" do
+      out = nil.public_methods.ai(:plain => true, :index => false).split("\n").grep(/is_a\?/).first
+      out.should =~ /^\s+is_a\?\(arg1\)\s+NilClass \(Kernel\)$/
+    end
+  end
+
+  describe "object.private_methods" do
+    it "index: should handle object.private_methods" do
+      out = nil.private_methods.ai(:plain => true).split("\n").grep(/sleep/).first
+      out.should =~ /^\s+\[\s*\d+\]\s+sleep\(\*arg1\)\s+NilClass \(Kernel\)$/
+    end
+
+    it "no index: should handle object.private_methods" do
+      out = nil.private_methods.ai(:plain => true, :index => false).split("\n").grep(/sleep/).first
+      out.should =~ /^\s+sleep\(\*arg1\)\s+NilClass \(Kernel\)$/
+    end
+  end
+
+  describe "object.protected_methods" do
+    it "index: should handle object.protected_methods" do
+      class Hello
+        protected
+        def m1; end
+        def m2; end
+      end
+      Hello.new.protected_methods.ai(:plain => true).should == "[\n    [0] m1() Hello\n    [1] m2() Hello\n]"
+    end
+
+    it "no index: should handle object.protected_methods" do
+      class Hello
+        protected
+        def m3(a,b); end
+      end
+      if RUBY_VERSION < '1.9.2'
+        Hello.new.protected_methods.ai(:plain => true, :index => false).should == "[\n     m3(arg1, arg2) Hello\n]"
+      else
+        Hello.new.protected_methods.ai(:plain => true, :index => false).should == "[\n     m3(a, b) Hello\n]"
+      end
+    end
+  end
+
+  describe "object.private_methods" do
+    it "index: should handle object.private_methods" do
+      class Hello
+        private
+        def m1; end
+        def m2; end
+      end
+
+      out = Hello.new.private_methods.ai(:plain => true).split("\n").grep(/m\d/)
+      out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(\)\s+Hello$/
+      out.last.should  =~ /^\s+\[\s*\d+\]\s+m2\(\)\s+Hello$/
+    end
+
+    it "no index: should handle object.private_methods" do
+      class Hello
+        private
+        def m3(a,b); end
+      end
+      out = Hello.new.private_methods.ai(:plain => true).split("\n").grep(/m\d/)
+      if RUBY_VERSION < '1.9.2'
+        out.first.should =~ /^\s+\[\s*\d+\]\s+m3\(arg1, arg2\)\s+Hello$/
+      else
+        out.first.should =~ /^\s+\[\s*\d+\]\s+m3\(a, b\)\s+Hello$/
+      end
+    end
+  end
+
+  describe "object.singleton_methods" do
+    it "index: should handle object.singleton_methods" do
+      class Hello
+        class << self
+          def m1; end
+          def m2; end
+        end
+      end
+      out = Hello.singleton_methods.ai(:plain => true).split("\n").grep(/m\d/)
+      out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(\)\s+Hello$/
+      out.last.should  =~ /^\s+\[\s*\d+\]\s+m2\(\)\s+Hello$/
+    end
+
+    it "no index: should handle object.singleton_methods" do
+      class Hello
+        def self.m3(a,b); end
+      end
+      out = Hello.singleton_methods.ai(:plain => true, :index => false).split("\n").grep(/m\d/)
+      if RUBY_VERSION < '1.9.2'
+        out.first.should =~ /^\s+m3\(arg1, arg2\)\s+Hello$/
+      else
+        out.first.should =~ /^\s+m3\(a, b\)\s+Hello$/
+      end
+    end
+  end
+end
+
+describe "Class methods" do
+  before do
+    stub_dotfile!
+  end
+
+  after do
+    Object.instance_eval{ remove_const :Hello } if defined?(Hello)
+  end
+
+  describe "class.instance_methods" do
+    it "index: should handle unbound class.instance_methods" do
+      class Hello
+        def m1; end
+        def m2; end
+      end
+      out = Hello.instance_methods.ai(:plain => true).split("\n").grep(/m\d/)
+      out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(\)\s+Hello\s\(unbound\)$/
+      out.last.should  =~ /^\s+\[\s*\d+\]\s+m2\(\)\s+Hello\s\(unbound\)$/
+    end
+
+    it "no index: should handle unbound class.instance_methods" do
+      class Hello
+        def m3(a,b); end
+      end
+      out = Hello.instance_methods.ai(:plain => true, :index => false).split("\n").grep(/m\d/)
+      if RUBY_VERSION < '1.9.2'
+        out.first.should =~ /^\s+m3\(arg1, arg2\)\s+Hello\s\(unbound\)$/
+      else
+        out.first.should =~ /^\s+m3\(a, b\)\s+Hello\s\(unbound\)$/
+      end
+    end
+  end
+
+  describe "class.public_instance_methods" do
+    it "index: should handle class.public_instance_methods" do
+      class Hello
+        def m1; end
+        def m2; end
+      end
+      out = Hello.public_instance_methods.ai(:plain => true).split("\n").grep(/m\d/)
+      out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(\)\s+Hello\s\(unbound\)$/
+      out.last.should  =~ /^\s+\[\s*\d+\]\s+m2\(\)\s+Hello\s\(unbound\)$/
+    end
+
+    it "no index: should handle class.public_instance_methods" do
+      class Hello
+        def m3(a,b); end
+      end
+      out = Hello.public_instance_methods.ai(:plain => true, :index => false).split("\n").grep(/m\d/)
+      if RUBY_VERSION < '1.9.2'
+        out.first.should =~ /^\s+m3\(arg1, arg2\)\s+Hello\s\(unbound\)$/
+      else
+        out.first.should =~ /^\s+m3\(a, b\)\s+Hello\s\(unbound\)$/
+      end
+    end
+  end
+
+  describe "class.protected_instance_methods" do
+    it "index: should handle class.protected_instance_methods" do
+      class Hello
+        protected
+        def m1; end
+        def m2; end
+      end
+      out = Hello.protected_instance_methods.ai(:plain => true).split("\n").grep(/m\d/)
+      out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(\)\s+Hello\s\(unbound\)$/
+      out.last.should  =~ /^\s+\[\s*\d+\]\s+m2\(\)\s+Hello\s\(unbound\)$/
+    end
+
+    it "no index: should handle class.protected_instance_methods" do
+      class Hello
+        protected
+        def m3(a,b); end
+      end
+      out = Hello.protected_instance_methods.ai(:plain => true, :index => false).split("\n").grep(/m\d/)
+      if RUBY_VERSION < '1.9.2'
+        out.first.should =~ /^\s+m3\(arg1, arg2\)\s+Hello\s\(unbound\)$/
+      else
+        out.first.should =~ /^\s+m3\(a, b\)\s+Hello\s\(unbound\)$/
+      end
+    end
+  end
+
+  describe "class.private_instance_methods" do
+    it "index: should handle class.private_instance_methods" do
+      class Hello
+        private
+        def m1; end
+        def m2; end
+      end
+      out = Hello.private_instance_methods.ai(:plain => true).split("\n").grep(/m\d/)
+      out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(\)\s+Hello\s\(unbound\)$/
+      out.last.should  =~ /^\s+\[\s*\d+\]\s+m2\(\)\s+Hello\s\(unbound\)$/
+    end
+
+    it "no index: should handle class.private_instance_methods" do
+      class Hello
+        private
+        def m3(a,b); end
+      end
+      out = Hello.private_instance_methods.ai(:plain => true, :index => false).split("\n").grep(/m\d/)
+      if RUBY_VERSION < '1.9.2'
+        out.first.should =~ /^\s+m3\(arg1, arg2\)\s+Hello\s\(unbound\)$/
+      else
+        out.first.should =~ /^\s+m3\(a, b\)\s+Hello\s\(unbound\)$/
+      end
+    end
+  end
+end
+
+if RUBY_VERSION >= '1.9.2'
+  describe "Ruby 1.9.2+ Method#parameters" do
+    before do
+      stub_dotfile!
+    end
+
+    after do
+      Object.instance_eval{ remove_const :Hello } if defined?(Hello)
+    end
+
+    it "()" do
+      class Hello
+        def m1; end
+      end
+      out = Hello.new.methods.ai(:plain => true).split("\n").grep(/m1/)
+      out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(\)\s+Hello$/
+    end
+
+    it ":req" do
+      class Hello
+        def m1(a, b, c); end
+      end
+      out = Hello.new.methods.ai(:plain => true).split("\n").grep(/m1/)
+      out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(a, b, c\)\s+Hello$/
+    end
+
+    it ":opt" do
+      class Hello
+        def m1(a, b = 1, c = 2); end # m1(a, *b, *c)
+      end
+      out = Hello.new.methods.ai(:plain => true).split("\n").grep(/m1/)
+      out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(a, \*b, \*c\)\s+Hello$/
+    end
+
+    it ":rest" do
+      class Hello
+        def m1(*a); end # m1(*a)
+      end
+      out = Hello.new.methods.ai(:plain => true).split("\n").grep(/m1/)
+      out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(\*a\)\s+Hello$/
+    end
+
+    it ":block" do
+      class Hello
+        def m1(a, b = nil, &blk); end # m1(a, *b, &blk)
+      end
+      out = Hello.new.methods.ai(:plain => true).split("\n").grep(/m1/)
+      out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(a, \*b, &blk\)\s+Hello$/
+    end
+  end
+end
+
+describe "Methods arrays" do
+  after do
+    Object.instance_eval{ remove_const :Hello } if defined?(Hello)
+    Object.instance_eval{ remove_const :World } if defined?(World)
+  end
+
+  it "obj1.methods - obj2.methods should be awesome printed" do
+    stub_dotfile!
+    class Hello
+      def self.m1; end
+    end
+    out = (Hello.methods - Class.methods).ai(:plain => true)
+    out.should == "[\n    [0] m1() Hello\n]"
+  end
+
+  it "obj1.methods & obj2.methods should be awesome printed" do
+    stub_dotfile!
+    class Hello
+      def self.m1; end
+      def self.m2; end
+    end
+    class World
+      def self.m1; end
+    end
+    out = (Hello.methods & World.methods - Class.methods).ai(:plain => true)
+    out.should == "[\n    [0] m1() Hello\n]"
+  end
+
+  it "obj1.methods.grep(pattern) should be awesome printed" do
+    stub_dotfile!
+    class Hello
+      def self.m1; end
+      def self.m2; end
+      def self.m3; end
+    end
+    out = Hello.methods.grep(/^m1$/).ai(:plain => true)
+    out.should == "[\n    [0] m1() Hello\n]"
+    out = Hello.methods.grep(/^m\d$/).ai(:plain => true)
+    out.should == "[\n    [0] m1() Hello\n    [1] m2() Hello\n    [2] m3() Hello\n]"
+  end
+
+  it "obj1.methods.grep(pattern, &block) should pass the matching string within the block" do
+    class Hello
+      def self.m_one; end
+      def self.m_two; end
+    end
+
+    out = Hello.methods.sort.grep(/^m_(.+)$/) { $1.to_sym }
+    out.should == [:one, :two]
+  end
+
+  it "obj1.methods.grep(pattern, &block) should be awesome printed" do
+    stub_dotfile!
+    class Hello
+      def self.m0; end
+      def self.none; end
+      def self.m1; end
+      def self.one; end
+    end
+
+    out = Hello.methods.grep(/^m(\d)$/) { %w(none one)[$1.to_i] }.ai(:plain => true)
+    out.should == "[\n    [0] none() Hello\n    [1]  one() Hello\n]"
+  end
+
+  # See https://github.com/michaeldv/awesome_print/issues/30 for details.
+  it "grepping methods and converting them to_sym should work as expected" do
+    class Hello
+      private
+      def him; end
+
+      def his
+        private_methods.grep(/^h..$/) { |n| n.to_sym }
+      end
+
+      def her
+        private_methods.grep(/^.e.$/) { |n| n.to_sym }
+      end
+    end
+
+    hello = Hello.new
+    (hello.send(:his) - hello.send(:her)).sort_by { |x| x.to_s }.should == [ :him, :his ]
+  end
+
+  it "appending garbage to methods array should not raise error" do
+    arr = 42.methods << [ :wtf ]
+    arr.ai(:plain => true).should_not raise_error(TypeError)
+    if RUBY_VERSION < '1.9.2'
+      arr.ai(:plain => true).should =~ /\s+wtf\(\?\)\s+\?/      # [ :wtf ].to_s => "wtf"
+    else
+      arr.ai(:plain => true).should =~ /\s+\[:wtf\]\(\?\)\s+\?/ # [ :wtf ].to_s => [:wtf]
+    end
+  end
+end
diff --git a/spec/misc_spec.rb b/spec/misc_spec.rb
new file mode 100644
index 0000000..2d21ee6
--- /dev/null
+++ b/spec/misc_spec.rb
@@ -0,0 +1,229 @@
+require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
+
+describe "AwesomePrint" do
+
+  describe "Misc" do
+    before do
+      stub_dotfile!
+    end
+
+    it "handle weird objects that return nil on inspect" do
+      weird = Class.new do
+        def inspect
+          nil
+        end
+      end
+      weird.new.ai(:plain => true).should == ''
+    end
+
+    it "handle frozen object.inspect" do
+      weird = Class.new do
+        def inspect
+          "ice".freeze
+        end
+      end
+      weird.new.ai(:plain => false).should == "ice"
+    end
+
+    # See https://github.com/michaeldv/awesome_print/issues/35
+    it "handle array grep when pattern contains / chapacter" do
+      hash = { "1/x" => 1,  "2//x" => :"2" }
+      grepped = hash.keys.sort.grep(/^(\d+)\//) { $1 }
+      grepped.ai(:plain => true, :multiline => false).should == '[ "1", "2" ]'
+    end
+
+    # See https://github.com/michaeldv/awesome_print/issues/85
+    if RUBY_VERSION >= "1.8.7"
+      it "handle array grep when a method is defined in C and thus doesn't have a binding" do
+        arr = (0..6).to_a
+        grepped = arr.grep(1..4, &:succ)
+        grepped.ai(:plain => true, :multiline => false).should == '[ 2, 3, 4, 5 ]'
+      end
+    end
+
+    it "returns value passed as a parameter" do
+      object = rand
+      self.stub!(:puts)
+      (ap object).should == object
+    end
+
+    # Require different file name this time (lib/ap.rb vs. lib/awesome_print).
+    it "several require 'awesome_print' should do no harm" do
+      require File.expand_path(File.dirname(__FILE__) + '/../lib/ap')
+      lambda { rand.ai }.should_not raise_error
+    end
+
+    it "format ENV as hash" do
+      ENV.ai(:plain => true).should == ENV.to_hash.ai(:plain => true)
+      ENV.ai.should == ENV.to_hash.ai
+    end
+  end
+
+  #------------------------------------------------------------------------------
+  describe "HTML output" do
+    before do
+      stub_dotfile!
+    end
+
+    it "wraps ap output with plain <pre> tag" do
+      markup = rand
+      markup.ai(:html => true, :plain => true).should == "<pre>#{markup}</pre>"
+    end
+
+    it "wraps ap output with <pre> tag with colorized <kbd>" do
+      markup = rand
+      markup.ai(:html => true).should == %Q|<pre><kbd style="color:blue">#{markup}</kbd></pre>|
+    end
+
+    it "wraps multiline ap output with <pre> tag with colorized <kbd>" do
+      markup = [ 1, :two, "three" ]
+      markup.ai(:html => true).should == <<-EOS.strip
+<pre>[
+    <kbd style="color:white">[0] </kbd><kbd style="color:blue">1</kbd>,
+    <kbd style="color:white">[1] </kbd><kbd style="color:darkcyan">:two</kbd>,
+    <kbd style="color:white">[2] </kbd><kbd style="color:brown">"three"</kbd>
+]</pre>
+EOS
+    end
+
+    it "wraps hash ap output with only an outer <pre> tag" do
+      markup = [ { "hello" => "world" } ]
+      markup.ai(:html => true).should == <<-EOS.strip
+<pre>[
+    <kbd style="color:white">[0] </kbd>{
+        "hello"<kbd style="color:slategray"> => </kbd><kbd style="color:brown">"world"</kbd>
+    }
+]</pre>
+    EOS
+    end
+
+    it "encodes HTML entities (plain)" do
+      markup = ' &<hello>'
+      markup.ai(:html => true, :plain => true).should == '<pre>" &<hello>"</pre>'
+    end
+
+    it "encodes HTML entities (color)" do
+      markup = ' &<hello>'
+      markup.ai(:html => true).should == '<pre><kbd style="color:brown">" &<hello>"</kbd></pre>'
+    end
+  end
+
+  #------------------------------------------------------------------------------
+  describe "AwesomePrint.defaults" do
+    before do
+      stub_dotfile!
+    end
+
+    after do
+      AwesomePrint.defaults = nil
+    end
+
+    # See https://github.com/michaeldv/awesome_print/issues/98
+    it "should properly merge the defaults" do
+      AwesomePrint.defaults = { :indent => -2, :sort_keys => true }
+      hash = { [0, 0, 255] => :yellow, :red => "rgb(255, 0, 0)", "magenta" => "rgb(255, 0, 255)" }
+      out = hash.ai(:plain => true)
+      out.should == <<-EOS.strip
+{
+  [ 0, 0, 255 ] => :yellow,
+  "magenta"     => "rgb(255, 0, 255)",
+  :red          => "rgb(255, 0, 0)"
+}
+EOS
+    end
+  end
+
+  #------------------------------------------------------------------------------
+  describe "Coexistence with the colorize gem" do
+    before do
+      stub_dotfile!
+    end
+
+    before do # Redefine String#red just like colorize gem does it.
+      @awesome_method = "".method(:red)
+
+      String.instance_eval do
+        define_method :red do   # Method arity is now 0 in Ruby 1.9+.
+          "[red]#{self}[/red]"
+        end
+      end
+    end
+
+    after do # Restore String#red method.
+      awesome_method = @awesome_method
+      String.instance_eval do
+        define_method :red, awesome_method
+      end
+    end
+
+    it "shoud not raise ArgumentError when formatting HTML" do
+      out = "hello".ai(:color => { :string => :red }, :html => true)
+      if RUBY_VERSION >= "1.9"
+        out.should == %Q|<pre>[red]<kbd style="color:red">"hello"</kbd>[/red]</pre>|
+      else
+        out.should == %Q|<pre>[red]"hello"[/red]</pre>|
+      end
+    end
+
+    it "shoud not raise ArgumentError when formatting HTML (shade color)" do
+      out = "hello".ai(:color => { :string => :redish }, :html => true)
+      out.should == %Q|<pre><kbd style="color:darkred">"hello"</kbd></pre>|
+    end
+
+    it "shoud not raise ArgumentError when formatting non-HTML" do
+      out = "hello".ai(:color => { :string => :red }, :html => false)
+      out.should == %Q|[red]"hello"[/red]|
+    end
+
+    it "shoud not raise ArgumentError when formatting non-HTML (shade color)" do
+      out = "hello".ai(:color => { :string => :redish }, :html => false)
+      out.should == %Q|\e[0;31m"hello"\e[0m|
+    end
+  end
+
+  #------------------------------------------------------------------------------
+  describe "Console" do
+    it "should detect IRB" do
+      class IRB; end
+      AwesomePrint.console?.should == true
+      AwesomePrint.rails_console?.should == false
+      Object.instance_eval{ remove_const :IRB }
+    end
+
+    it "should detect Pry" do
+      class Pry; end
+      AwesomePrint.console?.should == true
+      AwesomePrint.rails_console?.should == false
+      Object.instance_eval{ remove_const :Pry }
+    end
+
+    it "should detect Rails::Console" do
+      class IRB; end
+      class Rails; class Console; end; end
+      AwesomePrint.console?.should == true
+      AwesomePrint.rails_console?.should == true
+      Object.instance_eval{ remove_const :IRB }
+      Object.instance_eval{ remove_const :Rails }
+    end
+
+    it "should detect ENV['RAILS_ENV']" do
+      class Pry; end
+      ENV["RAILS_ENV"] = "development"
+      AwesomePrint.console?.should == true
+      AwesomePrint.rails_console?.should == true
+      Object.instance_eval{ remove_const :Pry }
+    end
+
+    it "should return the actual object when *not* running under console" do
+      capture! { ap([ 1, 2, 3 ]) }.should == [ 1, 2, 3 ]
+      capture! { ap({ :a => 1 }) }.should == { :a => 1 }
+    end
+
+    it "should return nil when running under console" do
+      class IRB; end
+      capture! { ap([ 1, 2, 3 ]) }.should == nil
+      capture! { ap({ :a => 1 }) }.should == nil
+      Object.instance_eval{ remove_const :IRB }
+    end
+  end
+end
diff --git a/spec/objects_spec.rb b/spec/objects_spec.rb
new file mode 100644
index 0000000..1802e9a
--- /dev/null
+++ b/spec/objects_spec.rb
@@ -0,0 +1,85 @@
+require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
+
+describe "Objects" do
+  before do
+    stub_dotfile!
+  end
+
+  after do
+    Object.instance_eval{ remove_const :Hello } if defined?(Hello)
+  end
+
+  describe "Formatting an object" do
+    it "attributes" do
+      class Hello
+        attr_reader   :abra
+        attr_writer   :ca
+        attr_accessor :dabra
+
+        def initialize
+          @abra, @ca, @dabra = 1, 2, 3
+        end
+      end
+
+      hello = Hello.new
+      out = hello.ai(:plain => true, :raw => true)
+      str = <<-EOS.strip
+#<Hello:0x01234567
+    attr_accessor :dabra = 3,
+    attr_reader :abra = 1,
+    attr_writer :ca = 2
+>
+EOS
+      out.gsub(/0x([a-f\d]+)/, "0x01234567").should == str
+      hello.ai(:plain => true, :raw => false).should == hello.inspect
+    end
+
+    it "instance variables" do
+      class Hello
+        def initialize
+          @abra, @ca, @dabra = 1, 2, 3
+        end
+      end
+
+      hello = Hello.new
+      out = hello.ai(:plain => true, :raw => true)
+      str = <<-EOS.strip
+#<Hello:0x01234567
+    @abra = 1,
+    @ca = 2,
+    @dabra = 3
+>
+EOS
+      out.gsub(/0x([a-f\d]+)/, "0x01234567").should == str
+      hello.ai(:plain => true, :raw => false).should == hello.inspect
+    end
+
+    it "attributes and instance variables" do
+      class Hello
+        attr_reader   :abra
+        attr_writer   :ca
+        attr_accessor :dabra
+
+        def initialize
+          @abra, @ca, @dabra = 1, 2, 3
+          @scooby, @dooby, @doo = 3, 2, 1
+        end
+      end
+
+      hello = Hello.new
+      out = hello.ai(:plain => true, :raw => true)
+      str = <<-EOS.strip
+#<Hello:0x01234567
+    @doo = 1,
+    @dooby = 2,
+    @scooby = 3,
+    attr_accessor :dabra = 3,
+    attr_reader :abra = 1,
+    attr_writer :ca = 2
+>
+EOS
+      out.gsub(/0x([a-f\d]+)/, "0x01234567").should == str
+      hello.ai(:plain => true, :raw => false).should == hello.inspect
+    end
+  end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
new file mode 100644
index 0000000..9a4ebab
--- /dev/null
+++ b/spec/spec_helper.rb
@@ -0,0 +1,64 @@
+# Copyright (c) 2010-2013 Michael Dvorkin
+#
+# Awesome Print is freely distributable under the terms of MIT license.
+# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
+#------------------------------------------------------------------------------
+#
+# Running specs from the command line:
+#   $ rake spec                   # Entire spec suite.
+#   $ rspec spec/objects_spec.rb  # Individual spec file.
+#
+# NOTE: To successfully run specs with Ruby 1.8.6 the older versions of
+# Bundler and RSpec gems are required:
+#
+# $ gem install bundler -v=1.0.2
+# $ gem install rspec -v=2.6.0
+#
+$LOAD_PATH.unshift(File.dirname(__FILE__))
+$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
+require 'awesome_print'
+
+def stub_dotfile!
+  dotfile = File.join(ENV["HOME"], ".aprc")
+  File.should_receive(:readable?).at_least(:once).with(dotfile).and_return(false)
+end
+
+def capture!
+  standard, $stdout = $stdout, StringIO.new
+  yield
+ensure
+  $stdout = standard
+end
+
+# The following is needed for the Infinity Test. It runs tests as subprocesses,
+# which sets STDOUT.tty? to false and would otherwise prematurely disallow colors.
+### AwesomePrint.force_colors!
+
+# Ruby 1.8.6 only: define missing String methods that are needed for the specs to pass.
+if RUBY_VERSION < '1.8.7'
+  class String
+    def shellescape # Taken from Ruby 1.9.2 standard library, see lib/shellwords.rb.
+      return "''" if self.empty?
+      str = self.dup
+      str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/n, "\\\\\\1")
+      str.gsub!(/\n/, "'\n'")
+      str
+    end
+
+    def start_with?(*prefixes)
+      prefixes.each do |prefix|
+        prefix = prefix.to_s
+        return true if prefix == self[0, prefix.size]
+      end
+      false
+    end
+
+    def end_with?(*suffixes)
+      suffixes.each do |suffix|
+        suffix = suffix.to_s
+        return true if suffix == self[-suffix.size, suffix.size]
+      end
+      false
+    end
+  end
+end

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-awesome-print.git



More information about the Pkg-ruby-extras-commits mailing list