From 4ac2bfd653127257ac1a07a8bed3abf1163fe039 Mon Sep 17 00:00:00 2001 From: Mike Dvorkin Date: Fri, 2 Apr 2010 21:43:46 -0700 Subject: [PATCH] Initial public commit --- .document | 5 - LICENSE | 3 +- README.md | 134 +++++++++++++++++++ README.rdoc | 17 --- Rakefile | 21 +-- VERSION | 2 +- awesome_print.gemspec | 63 +++++++++ init.rb | 1 + lib/ap.rb | 10 ++ lib/ap/awesome_print.rb | 194 +++++++++++++++++++++++++++ lib/ap/core_ext/kernel.rb | 14 ++ lib/ap/core_ext/string.rb | 21 +++ lib/ap/mixin/rails.rb | 60 +++++++++ rails/init.rb | 1 + spec/ap_spec.rb | 7 - spec/awesome_print_spec.rb | 261 +++++++++++++++++++++++++++++++++++++ spec/rails_spec.rb | 87 +++++++++++++ spec/string_spec.rb | 18 +++ 18 files changed, 879 insertions(+), 40 deletions(-) delete mode 100644 .document create mode 100644 README.md delete mode 100644 README.rdoc create mode 100644 awesome_print.gemspec create mode 100644 init.rb mode change 100644 => 100755 lib/ap.rb create mode 100755 lib/ap/awesome_print.rb create mode 100644 lib/ap/core_ext/kernel.rb create mode 100755 lib/ap/core_ext/string.rb create mode 100755 lib/ap/mixin/rails.rb create mode 100644 rails/init.rb delete mode 100644 spec/ap_spec.rb create mode 100644 spec/awesome_print_spec.rb create mode 100644 spec/rails_spec.rb create mode 100644 spec/string_spec.rb diff --git a/.document b/.document deleted file mode 100644 index ecf3673..0000000 --- a/.document +++ /dev/null @@ -1,5 +0,0 @@ -README.rdoc -lib/**/*.rb -bin/* -features/**/*.feature -LICENSE diff --git a/LICENSE b/LICENSE index 7aa375c..d85cb61 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,5 @@ -Copyright (c) 2009 Mike Dvorkin +Copyright (c) 2010 Michael Dvorkin +%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 diff --git a/README.md b/README.md new file mode 100644 index 0000000..7107cca --- /dev/null +++ b/README.md @@ -0,0 +1,134 @@ +## Awesome Print ## + Awesome Print is Ruby library that pretty prints Ruby objects in full color + exposing their internal structure with proper indentation. Rails ActiveRecord + objects are supported via included mixin. + +### Installation ### + $ # Installing as Ruby gem + $ gem install awesome_print + + # Installing as Rails plugin + $ ruby script/plugin install http://github.com/michaeldv/awesome_print_.git + + $ # Cloning the repository + $ git clone git://github.com/michaeldv/awesome_print_.git + +### Usage ### + require "ap" + ap(object, options = {}) + + Default options: + :miltiline => true, + :plain => false, + :colors => { + :array => :white, + :bignum => :blue, + :class => :yellow, + :date => :greenish, + :falseclass => :red, + :fixnum => :blue, + :float => :blue, + :hash => :gray, + :nilclass => :red, + :string => :yellowish, + :symbol => :cyanish, + :time => :greenish, + :trueclass => :green + } + + Supported color names: + :gray, :red, :green, :yellow, :blue, :purple, :cyan, :white + :black, :redish, :greenish, :yellowish, :blueish, :purpleish, :cyanish, :pale + +### Example (IRB) ### + $ irb + irb> require "ap" + irb> data = [ false, 42, %w(fourty two), { :now => Time.now, :class => Time.now.class, :distance => 42e42 } ] + irb> ap data + [ + [0] false, + [1] 42, + [2] [ + [0] "fourty", + [1] "two" + ], + [3] { + :class => Time < Object, + :now => Fri Apr 02 19:55:53 -0700 2010, + :distance => 4.2e+43 + } + ] + irb> ap data, :multiline => false + [ false, 42, [ "fourty", "two" ], { :class => Time < Object, :distance => 4.2e+43, :now => Fri Apr 02 19:44:52 -0700 2010 } ] + irb> + +### Example (Rails) ### + $ ruby script/console + Loading development environment (Rails 2.3.5) + rails> require "ap" + rails> ap Account.all(:limit => 2) + [ + [0] # { + :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@hayesdubuque.com", + :background_info => nil + }, + [1] # { + :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@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> + +### 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 me a pull request. + +### License ### + Copyright (c) 2010 Michael Dvorkin + %w(mike dvorkin.net) * "@" || %w(mike fatfreecrm.com) * "@" + + Released under the MIT license. See LICENSE file for details. diff --git a/README.rdoc b/README.rdoc deleted file mode 100644 index 4b5b0c6..0000000 --- a/README.rdoc +++ /dev/null @@ -1,17 +0,0 @@ -= ap - -Description goes here. - -== Note on Patches/Pull Requests - -* Fork the project. -* Make your feature addition or bug fix. -* Add tests for it. This is important so I don't break it in a - future version unintentionally. -* Commit, do not mess with rakefile, version, or history. - (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull) -* Send me a pull request. Bonus points for topic branches. - -== Copyright - -Copyright (c) 2010 Mike Dvorkin. See LICENSE for details. diff --git a/Rakefile b/Rakefile index 5f36d96..3d2b26b 100644 --- a/Rakefile +++ b/Rakefile @@ -4,13 +4,16 @@ require 'rake' begin require 'jeweler' Jeweler::Tasks.new do |gem| - gem.name = "ap" - gem.summary = %Q{TODO: one-line summary of your gem} - gem.description = %Q{TODO: longer description of your gem} + gem.name = "awesome_print" + gem.rubyforge_project = "awesome_print" + gem.summary = %Q{Pretty print Ruby objects with proper indentation and colors.} + gem.description = %Q{Great Ruby dubugging companion: pretty print Ruby objects to visualize their structure. Supports Rails ActiveRecord objects via included mixin.} gem.email = "mike@dvorkin.net" - gem.homepage = "http://github.com/michaeldv/ap" - gem.authors = ["Mike Dvorkin"] + gem.homepage = "http://github.com/michaeldv/awesome_print" + gem.authors = ["Michael Dvorkin"] gem.add_development_dependency "rspec", ">= 1.2.9" + gem.files = FileList["[A-Z]*", "lib/**/*.rb", "rails/*.rb", "spec/*", "init.rb"] + gem.has_rdoc = false # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings end Jeweler::GemcutterTasks.new @@ -38,8 +41,8 @@ require 'rake/rdoctask' Rake::RDocTask.new do |rdoc| version = File.exist?('VERSION') ? File.read('VERSION') : "" - rdoc.rdoc_dir = 'rdoc' - rdoc.title = "ap #{version}" - rdoc.rdoc_files.include('README*') - rdoc.rdoc_files.include('lib/**/*.rb') + rdoc.rdoc_dir = 'rdoc' + rdoc.title = "ap #{version}" + rdoc.rdoc_files.include('README*') + rdoc.rdoc_files.include('lib/**/*.rb') end diff --git a/VERSION b/VERSION index 77d6f4c..6e8bf73 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.0 +0.1.0 diff --git a/awesome_print.gemspec b/awesome_print.gemspec new file mode 100644 index 0000000..51c4d2b --- /dev/null +++ b/awesome_print.gemspec @@ -0,0 +1,63 @@ +# Generated by jeweler +# DO NOT EDIT THIS FILE DIRECTLY +# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = %q{awesome_print} + s.version = "0.1.0" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["Michael Dvorkin"] + s.date = %q{2010-04-02} + s.description = %q{Great Ruby dubugging companion: pretty print Ruby objects to visualize their structure. Supports Rails ActiveRecord objects via included mixin.} + s.email = %q{mike@dvorkin.net} + s.extra_rdoc_files = [ + "LICENSE", + "README.md" + ] + s.files = [ + "LICENSE", + "README.md", + "Rakefile", + "VERSION", + "init.rb", + "lib/ap.rb", + "lib/ap/awesome_print.rb", + "lib/ap/core_ext/kernel.rb", + "lib/ap/core_ext/string.rb", + "lib/ap/mixin/rails.rb", + "rails/init.rb", + "spec/awesome_print_spec.rb", + "spec/rails_spec.rb", + "spec/spec.opts", + "spec/spec_helper.rb", + "spec/string_spec.rb" + ] + s.homepage = %q{http://github.com/michaeldv/awesome_print} + s.rdoc_options = ["--charset=UTF-8"] + s.require_paths = ["lib"] + s.rubyforge_project = %q{awesome_print} + s.rubygems_version = %q{1.3.6} + s.summary = %q{Pretty print Ruby objects with proper indentation and colors.} + s.test_files = [ + "spec/awesome_print_spec.rb", + "spec/rails_spec.rb", + "spec/spec_helper.rb", + "spec/string_spec.rb" + ] + + if s.respond_to? :specification_version then + current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION + s.specification_version = 3 + + if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then + s.add_development_dependency(%q, [">= 1.2.9"]) + else + s.add_dependency(%q, [">= 1.2.9"]) + end + else + s.add_dependency(%q, [">= 1.2.9"]) + end +end + diff --git a/init.rb b/init.rb new file mode 100644 index 0000000..1b9329c --- /dev/null +++ b/init.rb @@ -0,0 +1 @@ +require File.join(File.dirname(__FILE__), "lib", "ap") diff --git a/lib/ap.rb b/lib/ap.rb old mode 100644 new mode 100755 index e69de29..5d3264b --- a/lib/ap.rb +++ b/lib/ap.rb @@ -0,0 +1,10 @@ +# Copyright (c) 2010 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 +#------------------------------------------------------------------------------ +require File.dirname(__FILE__) + "/ap/core_ext/string" +require File.dirname(__FILE__) + "/ap/core_ext/kernel" +require File.dirname(__FILE__) + "/ap/awesome_print" + +require File.dirname(__FILE__) + "/ap/mixin/rails" if defined?(::Rails) diff --git a/lib/ap/awesome_print.rb b/lib/ap/awesome_print.rb new file mode 100755 index 0000000..3c3fd46 --- /dev/null +++ b/lib/ap/awesome_print.rb @@ -0,0 +1,194 @@ +# Copyright (c) 2010 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 AwesomePrint + AP = :__awesome_print__ + CORE = [ :array, :hash, :class, :file, :dir ] + + def initialize(options = {}) + @options = { + :multiline => true, + :plain => false, + :indent => 4, + :color => { + :array => :white, + :bignum => :blue, + :class => :yellow, + :date => :greenish, + :falseclass => :red, + :fixnum => :blue, + :float => :blue, + :hash => :gray, + :nilclass => :red, + :string => :yellowish, + :symbol => :cyanish, + :time => :greenish, + :trueclass => :green + }.merge(options.delete(:color) || {}) + }.merge(options) + + @indentation = @options[:indent] + Thread.current[AP] ||= [] + end + + def puts(object) + Kernel.puts awesome(object) + end + + + private + + # Format an array. + #------------------------------------------------------------------------------ + def awesome_array(a) + if @options[:multiline] + width = (a.size - 1).to_s.size + data = a.inject([]) do |arr, item| + index = colorize("#{indent}[#{arr.size.to_s.rjust(width)}] ", :array) + indented do + arr << (index << awesome(item)) + end + end + "[\n" << data.join(",\n") << "\n#{outdent}]" + else + data = a.inject([]) { |arr, item| arr << awesome(item) } + "[ #{data.join(', ')} ]" + end + end + + # Format a hash. + #------------------------------------------------------------------------------ + def awesome_hash(h) + data = h.keys.inject([]) do |arr, key| + plain_single_line do + arr << [ awesome(key), h[key] ] + end + end + + width = data.map { |key, | key.size }.max + @indentation + + data = data.inject([]) do |arr, (key, value)| + formatted_key = (@options[:multiline] ? key.rjust(width) : key) << colorize(" => ", :hash) + indented do + arr << (formatted_key << awesome(value)) + end + end + if @options[:multiline] + "{\n" << data.join(",\n") << "\n#{outdent}}" + else + "{ #{data.join(', ')} }" + end + end + + # Format Class object. + #------------------------------------------------------------------------------ + def awesome_class(c) + if superclass = c.superclass # <-- Assign and test if nil. + awesome_self(c, :with => " < #{superclass}") + else + awesome_self(c) + end + end + + # Format File object. + #------------------------------------------------------------------------------ + def awesome_file(f) + ls = File.directory?(f) ? `ls -adlF #{f.path}` : `ls -alF #{f.path}` + awesome_self(f, :with => ls.empty? ? nil : "\n#{ls.chop}") + end + + # Format Dir object. + #------------------------------------------------------------------------------ + def awesome_dir(d) + ls = `ls -alF #{d.path}` + awesome_self(d, :with => ls.empty? ? nil : "\n#{ls.chop}") + end + + # Catch all method to format an arbitrary object. + #------------------------------------------------------------------------------ + def awesome_self(object, appear = {}) + colorize(object.inspect << appear[:with].to_s, appear[:as] || declassify(object)) + 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 + send(:"awesome_#{printable(object)}", object) + ensure + Thread.current[AP].pop + end + end + end + + # Format nested data, for example: + # arr = [1, 2]; arr << arr + # => [1,2, [...]] + # hsh = { :a => 1 }; hsh[:b] = hsh + # => { :a => 1, :b => {...} } + #------------------------------------------------------------------------------ + def nested(object) + case printable(object) + when :array then colorize("[...]", :array) + when :hash then colorize("{...}", :hash) + else colorize("...#{object.class}...", :class) + end + end + + # Return one of the "core" types that have a formatter of :self otherwise. + #------------------------------------------------------------------------------ + def printable(object) + CORE.grep(declassify(object))[0] || :self + end + + # Turn class name into symbol, ex: Hello::World => :hello_world. + #------------------------------------------------------------------------------ + def declassify(object) + object.class.to_s.gsub(/:+/, "_").downcase.to_sym + end + + # Pick the color and apply it to the given string as necessary. + #------------------------------------------------------------------------------ + def colorize(s, type) + if @options[:plain] || @options[:color][type].nil? + s + else + s.send(@options[:color][type]) + end + end + + # Format hash keys as plain string 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 + + #------------------------------------------------------------------------------ + def indented + @indentation += @options[:indent] + yield + ensure + @indentation -= @options[:indent] + end + + #------------------------------------------------------------------------------ + def indent + ' ' * @indentation + end + + #------------------------------------------------------------------------------ + def outdent + ' ' * (@indentation - @options[:indent]) + end + +end diff --git a/lib/ap/core_ext/kernel.rb b/lib/ap/core_ext/kernel.rb new file mode 100644 index 0000000..977e64e --- /dev/null +++ b/lib/ap/core_ext/kernel.rb @@ -0,0 +1,14 @@ +# Copyright (c) 2010 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 ap(object, options = {}) + ap = AwesomePrint.new(options) + ap.puts object + end + + module_function :ap +end diff --git a/lib/ap/core_ext/string.rb b/lib/ap/core_ext/string.rb new file mode 100755 index 0000000..dcd668c --- /dev/null +++ b/lib/ap/core_ext/string.rb @@ -0,0 +1,21 @@ +# Copyright (c) 2010 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 # :nodoc: + + [ :gray, :red, :green, :yellow, :blue, :purple, :cyan, :white ].each_with_index do |color, i| + if STDOUT.tty? && ENV['TERM'] && ENV['TERM'] != 'dumb' + define_method color do "\033[1;#{30+i}m#{self}\033[0m" end + define_method :"#{color}ish" do "\033[0;#{30+i}m#{self}\033[0m" end + else + define_method color do self end + alias :"#{color}ish" color # <- This break Rdoc: Name or symbol expected (got # :time) + end + +end + +AwesomePrint.send(:include, AwesomePrintRails) diff --git a/rails/init.rb b/rails/init.rb new file mode 100644 index 0000000..c6a8cea --- /dev/null +++ b/rails/init.rb @@ -0,0 +1 @@ +require File.join(File.dirname(__FILE__), "..", "init") diff --git a/spec/ap_spec.rb b/spec/ap_spec.rb deleted file mode 100644 index 1e9dce0..0000000 --- a/spec/ap_spec.rb +++ /dev/null @@ -1,7 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/spec_helper') - -describe "Ap" do - it "fails" do - fail "hey buddy, you should probably rename this file and start specing for real" - end -end diff --git a/spec/awesome_print_spec.rb b/spec/awesome_print_spec.rb new file mode 100644 index 0000000..9c83e48 --- /dev/null +++ b/spec/awesome_print_spec.rb @@ -0,0 +1,261 @@ +require File.expand_path(File.dirname(__FILE__) + '/spec_helper') + +describe "AwesomePrint" do + before(:each) do + @color_ap = AwesomePrint.new + @plain_ap = AwesomePrint.new(:plain => true) + end + + #------------------------------------------------------------------------------ + describe "Array" do + before(:each) do + @arr = [ 1, :two, "three", [ nil, [ true, false] ] ] + end + + it "plain multiline" do + ap = AwesomePrint.new(:plain => true) + ap.send(:awesome, @arr).should == <<-EOS.strip +[ + [0] 1, + [1] :two, + [2] "three", + [3] [ + [0] nil, + [1] [ + [0] true, + [1] false + ] + ] +] +EOS + end + + it "plain multiline indented" do + ap = AwesomePrint.new(:plain => true, :indent => 2) + ap.send(:awesome, @arr).should == <<-EOS.strip +[ + [0] 1, + [1] :two, + [2] "three", + [3] [ + [0] nil, + [1] [ + [0] true, + [1] false + ] + ] +] +EOS + end + + it "plain single line" do + ap = AwesomePrint.new(:plain => true, :multiline => false) + ap.send(:awesome, @arr).should == '[ 1, :two, "three", [ nil, [ true, false ] ] ]' + end + + it "colored multiline" do + ap = AwesomePrint.new + ap.send(:awesome, @arr).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 + ap = AwesomePrint.new(:indent => 8) + ap.send(:awesome, @arr).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 + ap = AwesomePrint.new(:multiline => false) + ap.send(:awesome, @arr).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(:each) do + @arr = [ 1, 2 ] + @arr << @arr + end + + it "plain multiline" do + ap = AwesomePrint.new(:plain => true) + ap.send(:awesome, @arr).should == <<-EOS.strip +[ + [0] 1, + [1] 2, + [2] [...] +] +EOS + end + + it "plain single line" do + ap = AwesomePrint.new(:plain => true, :multiline => false) + ap.send(:awesome, @arr).should == "[ 1, 2, [...] ]" + end + end + + #------------------------------------------------------------------------------ + describe "Hash" do + before(:each) do + @hash = { 1 => { :sym => { "str" => { [1, 2, 3] => { { :k => :v } => Hash } } } } } + end + + it "plain multiline" do + ap = AwesomePrint.new(:plain => true) + ap.send(:awesome, @hash).should == <<-EOS.strip +{ + 1 => { + :sym => { + "str" => { + [ 1, 2, 3 ] => { + { :k => :v } => Hash < Object + } + } + } + } +} +EOS + end + + it "plain multiline indented" do + ap = AwesomePrint.new(:plain => true, :indent => 1) + ap.send(:awesome, @hash).should == <<-EOS.strip +{ + 1 => { + :sym => { + "str" => { + [ 1, 2, 3 ] => { + { :k => :v } => Hash < Object + } + } + } + } +} +EOS + end + + it "plain single line" do + ap = AwesomePrint.new(:plain => true, :multiline => false) + ap.send(:awesome, @hash).should == '{ 1 => { :sym => { "str" => { [ 1, 2, 3 ] => { { :k => :v } => Hash < Object } } } } }' + end + + it "colored multiline" do + ap = AwesomePrint.new + ap.send(:awesome, @hash).should == <<-EOS.strip +{ + 1\e[1;30m => \e[0m{ + :sym\e[1;30m => \e[0m{ + \"str\"\e[1;30m => \e[0m{ + [ 1, 2, 3 ]\e[1;30m => \e[0m{ + { :k => :v }\e[1;30m => \e[0m\e[1;33mHash < Object\e[0m + } + } + } + } +} +EOS + end + + it "colored multiline indented" do + ap = AwesomePrint.new(:indent => 2) + ap.send(:awesome, @hash).should == <<-EOS.strip +{ + 1\e[1;30m => \e[0m{ + :sym\e[1;30m => \e[0m{ + \"str\"\e[1;30m => \e[0m{ + [ 1, 2, 3 ]\e[1;30m => \e[0m{ + { :k => :v }\e[1;30m => \e[0m\e[1;33mHash < Object\e[0m + } + } + } + } +} +EOS + end + + it "colored single line" do + ap = AwesomePrint.new(:multiline => false) + ap.send(:awesome, @hash).should == "{ 1\e[1;30m => \e[0m{ :sym\e[1;30m => \e[0m{ \"str\"\e[1;30m => \e[0m{ [ 1, 2, 3 ]\e[1;30m => \e[0m{ { :k => :v }\e[1;30m => \e[0m\e[1;33mHash < Object\e[0m } } } } }" + end + + end + + #------------------------------------------------------------------------------ + describe "Nested Hash" do + before(:each) do + @hash = {} + @hash[:a] = @hash + end + + it "plain multiline" do + ap = AwesomePrint.new(:plain => true) + ap.send(:awesome, @hash).should == <<-EOS.strip +{ + :a => {...} +} +EOS + end + + it "plain single line" do + ap = AwesomePrint.new(:plain => true, :multiline => false) + ap.send(:awesome, @hash).should == '{ :a => {...} }' + end + end + + #------------------------------------------------------------------------------ + describe "Class" do + it "shoud show superclass (plain)" do + ap = AwesomePrint.new(:plain => true) + ap.send(:awesome, self.class).should == "#{self.class} < #{self.class.superclass}" + end + + it "shoud show superclass (color)" do + ap = AwesomePrint.new + ap.send(:awesome_class, self.class).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| + @plain_ap.send(:awesome_file, f).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| + @plain_ap.send(:awesome_dir, d).should == "#{d.inspect}\n" << `ls -alF #{d.path}`.chop + end + end + end + +end diff --git a/spec/rails_spec.rb b/spec/rails_spec.rb new file mode 100644 index 0000000..8a38d87 --- /dev/null +++ b/spec/rails_spec.rb @@ -0,0 +1,87 @@ +require File.expand_path(File.dirname(__FILE__) + '/spec_helper') + +if defined?(::Rails) + + # Create tableless ActiveRecord model. + #------------------------------------------------------------------------------ + class User < ActiveRecord::Base + def self.columns() + @columns ||= [] + end + + def self.column(name, sql_type = nil, default = nil, null = true) + columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null) + end + + def self.table_exists? + true + end + + column :id, :integer + column :name, :string + column :rank, :integer + column :admin, :boolean + column :created_at, :datetime + end + + #------------------------------------------------------------------------------ + describe "ActiveRecord instance" do + before(:each) do + @diana = User.new(:name => "Diana", :rank => 1, :admin => false, :created_at => "1992-10-10 12:30:00") + @laura = User.new(:name => "Laura", :rank => 2, :admin => true, :created_at => "2003-05-26 14:15:00") + @ap = AwesomePrint.new(:plain => true) + end + + it "display single record" do + out = @ap.send(:awesome, @diana) + out.gsub(/0x([a-f\d]+)/, "0x01234567").should == <<-EOS.strip +# { + :id => nil, + :name => "Diana", + :rank => 1, + :admin => false, + :created_at => Sat, 10 Oct 1992 12:30:00 UTC +00:00 +} +EOS + end + + it "display multiple records" do + out = @ap.send(:awesome, [ @diana, @laura ]) + out.gsub(/0x([a-f\d]+)/, "0x01234567").should == <<-EOS.strip +[ + [0] # { + :id => nil, + :name => "Diana", + :rank => 1, + :admin => false, + :created_at => Sat, 10 Oct 1992 12:30:00 UTC +00:00 + }, + [1] # { + :id => nil, + :name => "Laura", + :rank => 2, + :admin => true, + :created_at => Mon, 26 May 2003 14:15:00 UTC +00:00 + } +] +EOS + end + end + + #------------------------------------------------------------------------------ + describe "ActiveRecord class" do + it "should" do + @ap = AwesomePrint.new(:plain => true) + @ap.send(:awesome, User).should == <<-EOS.strip +class User < ActiveRecord::Base { + :id => :integer, + :name => :string, + :rank => :integer, + :admin => :boolean, + :created_at => :datetime +} +EOS + end + end + +end diff --git a/spec/string_spec.rb b/spec/string_spec.rb new file mode 100644 index 0000000..6cdd8d8 --- /dev/null +++ b/spec/string_spec.rb @@ -0,0 +1,18 @@ +require File.expand_path(File.dirname(__FILE__) + '/spec_helper') + +describe "String extensions" do + [ :gray, :red, :green, :yellow, :blue, :purple, :cyan, :white ].each_with_index do |color, i| + it "should have #{color} color" do + color.to_s.send(color).should == "\033[1;#{30+i}m#{color}\033[0m" + end + + it "should have #{color}ish color" do + color.to_s.send(:"#{color}ish").should == "\033[0;#{30+i}m#{color}\033[0m" + end + end + + it "should have black and pale colors" do + "black".send(:black).should == "black".send(:grayish) + "pale".send(:pale).should == "pale".send(:whiteish) + end +end