awesome_print 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +21 -0
- data/README.md +134 -0
- data/Rakefile +48 -0
- data/VERSION +1 -0
- data/init.rb +1 -0
- data/lib/ap.rb +10 -0
- data/lib/ap/awesome_print.rb +194 -0
- data/lib/ap/core_ext/kernel.rb +14 -0
- data/lib/ap/core_ext/string.rb +21 -0
- data/lib/ap/mixin/rails.rb +60 -0
- data/rails/init.rb +1 -0
- data/spec/awesome_print_spec.rb +261 -0
- data/spec/rails_spec.rb +87 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/string_spec.rb +18 -0
- metadata +94 -0
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2010 Michael Dvorkin
|
2
|
+
%w(mike dvorkin.net) * "@" || %w(mike fatfreecrm.com) * "@"
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
## Awesome Print ##
|
2
|
+
Awesome Print is Ruby library that pretty prints Ruby objects in full color
|
3
|
+
exposing their internal structure with proper indentation. Rails ActiveRecord
|
4
|
+
objects are supported via included mixin.
|
5
|
+
|
6
|
+
### Installation ###
|
7
|
+
$ # Installing as Ruby gem
|
8
|
+
$ gem install awesome_print
|
9
|
+
|
10
|
+
# Installing as Rails plugin
|
11
|
+
$ ruby script/plugin install http://github.com/michaeldv/awesome_print_.git
|
12
|
+
|
13
|
+
$ # Cloning the repository
|
14
|
+
$ git clone git://github.com/michaeldv/awesome_print_.git
|
15
|
+
|
16
|
+
### Usage ###
|
17
|
+
require "ap"
|
18
|
+
ap(object, options = {})
|
19
|
+
|
20
|
+
Default options:
|
21
|
+
:miltiline => true,
|
22
|
+
:plain => false,
|
23
|
+
:colors => {
|
24
|
+
:array => :white,
|
25
|
+
:bignum => :blue,
|
26
|
+
:class => :yellow,
|
27
|
+
:date => :greenish,
|
28
|
+
:falseclass => :red,
|
29
|
+
:fixnum => :blue,
|
30
|
+
:float => :blue,
|
31
|
+
:hash => :gray,
|
32
|
+
:nilclass => :red,
|
33
|
+
:string => :yellowish,
|
34
|
+
:symbol => :cyanish,
|
35
|
+
:time => :greenish,
|
36
|
+
:trueclass => :green
|
37
|
+
}
|
38
|
+
|
39
|
+
Supported color names:
|
40
|
+
:gray, :red, :green, :yellow, :blue, :purple, :cyan, :white
|
41
|
+
:black, :redish, :greenish, :yellowish, :blueish, :purpleish, :cyanish, :pale
|
42
|
+
|
43
|
+
### Example (IRB) ###
|
44
|
+
$ irb
|
45
|
+
irb> require "ap"
|
46
|
+
irb> data = [ false, 42, %w(fourty two), { :now => Time.now, :class => Time.now.class, :distance => 42e42 } ]
|
47
|
+
irb> ap data
|
48
|
+
[
|
49
|
+
[0] false,
|
50
|
+
[1] 42,
|
51
|
+
[2] [
|
52
|
+
[0] "fourty",
|
53
|
+
[1] "two"
|
54
|
+
],
|
55
|
+
[3] {
|
56
|
+
:class => Time < Object,
|
57
|
+
:now => Fri Apr 02 19:55:53 -0700 2010,
|
58
|
+
:distance => 4.2e+43
|
59
|
+
}
|
60
|
+
]
|
61
|
+
irb> ap data, :multiline => false
|
62
|
+
[ false, 42, [ "fourty", "two" ], { :class => Time < Object, :distance => 4.2e+43, :now => Fri Apr 02 19:44:52 -0700 2010 } ]
|
63
|
+
irb>
|
64
|
+
|
65
|
+
### Example (Rails) ###
|
66
|
+
$ ruby script/console
|
67
|
+
Loading development environment (Rails 2.3.5)
|
68
|
+
rails> require "ap"
|
69
|
+
rails> ap Account.all(:limit => 2)
|
70
|
+
[
|
71
|
+
[0] #<Account:0x1033220b8> {
|
72
|
+
:id => 1,
|
73
|
+
:user_id => 5,
|
74
|
+
:assigned_to => 7,
|
75
|
+
:name => "Hayes-DuBuque",
|
76
|
+
:access => "Public",
|
77
|
+
:website => "http://www.hayesdubuque.com",
|
78
|
+
:toll_free_phone => "1-800-932-6571",
|
79
|
+
:phone => "(111)549-5002",
|
80
|
+
:fax => "(349)415-2266",
|
81
|
+
:deleted_at => nil,
|
82
|
+
:created_at => Sat, 06 Mar 2010 09:46:10 UTC +00:00,
|
83
|
+
:updated_at => Sat, 06 Mar 2010 16:33:10 UTC +00:00,
|
84
|
+
:email => "info@hayesdubuque.com",
|
85
|
+
:background_info => nil
|
86
|
+
},
|
87
|
+
[1] #<Account:0x103321ff0> {
|
88
|
+
:id => 2,
|
89
|
+
:user_id => 4,
|
90
|
+
:assigned_to => 4,
|
91
|
+
:name => "Ziemann-Streich",
|
92
|
+
:access => "Public",
|
93
|
+
:website => "http://www.ziemannstreich.com",
|
94
|
+
:toll_free_phone => "1-800-871-0619",
|
95
|
+
:phone => "(042)056-1534",
|
96
|
+
:fax => "(106)017-8792",
|
97
|
+
:deleted_at => nil,
|
98
|
+
:created_at => Tue, 09 Feb 2010 13:32:10 UTC +00:00,
|
99
|
+
:updated_at => Tue, 09 Feb 2010 20:05:01 UTC +00:00,
|
100
|
+
:email => "info@ziemannstreich.com",
|
101
|
+
:background_info => nil
|
102
|
+
}
|
103
|
+
]
|
104
|
+
rails> ap Account
|
105
|
+
class Account < ActiveRecord::Base {
|
106
|
+
:id => :integer,
|
107
|
+
:user_id => :integer,
|
108
|
+
:assigned_to => :integer,
|
109
|
+
:name => :string,
|
110
|
+
:access => :string,
|
111
|
+
:website => :string,
|
112
|
+
:toll_free_phone => :string,
|
113
|
+
:phone => :string,
|
114
|
+
:fax => :string,
|
115
|
+
:deleted_at => :datetime,
|
116
|
+
:created_at => :datetime,
|
117
|
+
:updated_at => :datetime,
|
118
|
+
:email => :string,
|
119
|
+
:background_info => :string
|
120
|
+
}
|
121
|
+
rails>
|
122
|
+
|
123
|
+
### Note on Patches/Pull Requests ###
|
124
|
+
* Fork the project on Github.
|
125
|
+
* Make your feature addition or bug fix.
|
126
|
+
* Add specs for it, making sure $ rake spec is all green.
|
127
|
+
* Commit, do not mess with rakefile, version, or history.
|
128
|
+
* Send me a pull request.
|
129
|
+
|
130
|
+
### License ###
|
131
|
+
Copyright (c) 2010 Michael Dvorkin
|
132
|
+
%w(mike dvorkin.net) * "@" || %w(mike fatfreecrm.com) * "@"
|
133
|
+
|
134
|
+
Released under the MIT license. See LICENSE file for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "awesome_print"
|
8
|
+
gem.rubyforge_project = "awesome_print"
|
9
|
+
gem.summary = %Q{Pretty print Ruby objects with proper indentation and colors.}
|
10
|
+
gem.description = %Q{Great Ruby dubugging companion: pretty print Ruby objects to visualize their structure. Supports Rails ActiveRecord objects via included mixin.}
|
11
|
+
gem.email = "mike@dvorkin.net"
|
12
|
+
gem.homepage = "http://github.com/michaeldv/awesome_print"
|
13
|
+
gem.authors = ["Michael Dvorkin"]
|
14
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
15
|
+
gem.files = FileList["[A-Z]*", "lib/**/*.rb", "rails/*.rb", "spec/*", "init.rb"]
|
16
|
+
gem.has_rdoc = false
|
17
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
|
+
end
|
19
|
+
Jeweler::GemcutterTasks.new
|
20
|
+
rescue LoadError
|
21
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'spec/rake/spectask'
|
25
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
26
|
+
spec.libs << 'lib' << 'spec'
|
27
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
28
|
+
end
|
29
|
+
|
30
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
31
|
+
spec.libs << 'lib' << 'spec'
|
32
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
33
|
+
spec.rcov = true
|
34
|
+
end
|
35
|
+
|
36
|
+
task :spec => :check_dependencies
|
37
|
+
|
38
|
+
task :default => :spec
|
39
|
+
|
40
|
+
require 'rake/rdoctask'
|
41
|
+
Rake::RDocTask.new do |rdoc|
|
42
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
43
|
+
|
44
|
+
rdoc.rdoc_dir = 'rdoc'
|
45
|
+
rdoc.title = "ap #{version}"
|
46
|
+
rdoc.rdoc_files.include('README*')
|
47
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
48
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "lib", "ap")
|
data/lib/ap.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# Copyright (c) 2010 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Awesome Print is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
require File.dirname(__FILE__) + "/ap/core_ext/string"
|
7
|
+
require File.dirname(__FILE__) + "/ap/core_ext/kernel"
|
8
|
+
require File.dirname(__FILE__) + "/ap/awesome_print"
|
9
|
+
|
10
|
+
require File.dirname(__FILE__) + "/ap/mixin/rails" if defined?(::Rails)
|
@@ -0,0 +1,194 @@
|
|
1
|
+
# Copyright (c) 2010 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Awesome Print is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
class AwesomePrint
|
7
|
+
AP = :__awesome_print__
|
8
|
+
CORE = [ :array, :hash, :class, :file, :dir ]
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
@options = {
|
12
|
+
:multiline => true,
|
13
|
+
:plain => false,
|
14
|
+
:indent => 4,
|
15
|
+
:color => {
|
16
|
+
:array => :white,
|
17
|
+
:bignum => :blue,
|
18
|
+
:class => :yellow,
|
19
|
+
:date => :greenish,
|
20
|
+
:falseclass => :red,
|
21
|
+
:fixnum => :blue,
|
22
|
+
:float => :blue,
|
23
|
+
:hash => :gray,
|
24
|
+
:nilclass => :red,
|
25
|
+
:string => :yellowish,
|
26
|
+
:symbol => :cyanish,
|
27
|
+
:time => :greenish,
|
28
|
+
:trueclass => :green
|
29
|
+
}.merge(options.delete(:color) || {})
|
30
|
+
}.merge(options)
|
31
|
+
|
32
|
+
@indentation = @options[:indent]
|
33
|
+
Thread.current[AP] ||= []
|
34
|
+
end
|
35
|
+
|
36
|
+
def puts(object)
|
37
|
+
Kernel.puts awesome(object)
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# Format an array.
|
44
|
+
#------------------------------------------------------------------------------
|
45
|
+
def awesome_array(a)
|
46
|
+
if @options[:multiline]
|
47
|
+
width = (a.size - 1).to_s.size
|
48
|
+
data = a.inject([]) do |arr, item|
|
49
|
+
index = colorize("#{indent}[#{arr.size.to_s.rjust(width)}] ", :array)
|
50
|
+
indented do
|
51
|
+
arr << (index << awesome(item))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
"[\n" << data.join(",\n") << "\n#{outdent}]"
|
55
|
+
else
|
56
|
+
data = a.inject([]) { |arr, item| arr << awesome(item) }
|
57
|
+
"[ #{data.join(', ')} ]"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Format a hash.
|
62
|
+
#------------------------------------------------------------------------------
|
63
|
+
def awesome_hash(h)
|
64
|
+
data = h.keys.inject([]) do |arr, key|
|
65
|
+
plain_single_line do
|
66
|
+
arr << [ awesome(key), h[key] ]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
width = data.map { |key, | key.size }.max + @indentation
|
71
|
+
|
72
|
+
data = data.inject([]) do |arr, (key, value)|
|
73
|
+
formatted_key = (@options[:multiline] ? key.rjust(width) : key) << colorize(" => ", :hash)
|
74
|
+
indented do
|
75
|
+
arr << (formatted_key << awesome(value))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
if @options[:multiline]
|
79
|
+
"{\n" << data.join(",\n") << "\n#{outdent}}"
|
80
|
+
else
|
81
|
+
"{ #{data.join(', ')} }"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Format Class object.
|
86
|
+
#------------------------------------------------------------------------------
|
87
|
+
def awesome_class(c)
|
88
|
+
if superclass = c.superclass # <-- Assign and test if nil.
|
89
|
+
awesome_self(c, :with => " < #{superclass}")
|
90
|
+
else
|
91
|
+
awesome_self(c)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Format File object.
|
96
|
+
#------------------------------------------------------------------------------
|
97
|
+
def awesome_file(f)
|
98
|
+
ls = File.directory?(f) ? `ls -adlF #{f.path}` : `ls -alF #{f.path}`
|
99
|
+
awesome_self(f, :with => ls.empty? ? nil : "\n#{ls.chop}")
|
100
|
+
end
|
101
|
+
|
102
|
+
# Format Dir object.
|
103
|
+
#------------------------------------------------------------------------------
|
104
|
+
def awesome_dir(d)
|
105
|
+
ls = `ls -alF #{d.path}`
|
106
|
+
awesome_self(d, :with => ls.empty? ? nil : "\n#{ls.chop}")
|
107
|
+
end
|
108
|
+
|
109
|
+
# Catch all method to format an arbitrary object.
|
110
|
+
#------------------------------------------------------------------------------
|
111
|
+
def awesome_self(object, appear = {})
|
112
|
+
colorize(object.inspect << appear[:with].to_s, appear[:as] || declassify(object))
|
113
|
+
end
|
114
|
+
|
115
|
+
# Dispatcher that detects data nesting and invokes object-aware formatter.
|
116
|
+
#------------------------------------------------------------------------------
|
117
|
+
def awesome(object)
|
118
|
+
if Thread.current[AP].include?(object.object_id)
|
119
|
+
nested(object)
|
120
|
+
else
|
121
|
+
begin
|
122
|
+
Thread.current[AP] << object.object_id
|
123
|
+
send(:"awesome_#{printable(object)}", object)
|
124
|
+
ensure
|
125
|
+
Thread.current[AP].pop
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Format nested data, for example:
|
131
|
+
# arr = [1, 2]; arr << arr
|
132
|
+
# => [1,2, [...]]
|
133
|
+
# hsh = { :a => 1 }; hsh[:b] = hsh
|
134
|
+
# => { :a => 1, :b => {...} }
|
135
|
+
#------------------------------------------------------------------------------
|
136
|
+
def nested(object)
|
137
|
+
case printable(object)
|
138
|
+
when :array then colorize("[...]", :array)
|
139
|
+
when :hash then colorize("{...}", :hash)
|
140
|
+
else colorize("...#{object.class}...", :class)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Return one of the "core" types that have a formatter of :self otherwise.
|
145
|
+
#------------------------------------------------------------------------------
|
146
|
+
def printable(object)
|
147
|
+
CORE.grep(declassify(object))[0] || :self
|
148
|
+
end
|
149
|
+
|
150
|
+
# Turn class name into symbol, ex: Hello::World => :hello_world.
|
151
|
+
#------------------------------------------------------------------------------
|
152
|
+
def declassify(object)
|
153
|
+
object.class.to_s.gsub(/:+/, "_").downcase.to_sym
|
154
|
+
end
|
155
|
+
|
156
|
+
# Pick the color and apply it to the given string as necessary.
|
157
|
+
#------------------------------------------------------------------------------
|
158
|
+
def colorize(s, type)
|
159
|
+
if @options[:plain] || @options[:color][type].nil?
|
160
|
+
s
|
161
|
+
else
|
162
|
+
s.send(@options[:color][type])
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# Format hash keys as plain string regardless of underlying data type.
|
167
|
+
#------------------------------------------------------------------------------
|
168
|
+
def plain_single_line
|
169
|
+
plain, multiline = @options[:plain], @options[:multiline]
|
170
|
+
@options[:plain], @options[:multiline] = true, false
|
171
|
+
yield
|
172
|
+
ensure
|
173
|
+
@options[:plain], @options[:multiline] = plain, multiline
|
174
|
+
end
|
175
|
+
|
176
|
+
#------------------------------------------------------------------------------
|
177
|
+
def indented
|
178
|
+
@indentation += @options[:indent]
|
179
|
+
yield
|
180
|
+
ensure
|
181
|
+
@indentation -= @options[:indent]
|
182
|
+
end
|
183
|
+
|
184
|
+
#------------------------------------------------------------------------------
|
185
|
+
def indent
|
186
|
+
' ' * @indentation
|
187
|
+
end
|
188
|
+
|
189
|
+
#------------------------------------------------------------------------------
|
190
|
+
def outdent
|
191
|
+
' ' * (@indentation - @options[:indent])
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Copyright (c) 2010 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Awesome Print is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
module Kernel
|
7
|
+
|
8
|
+
def ap(object, options = {})
|
9
|
+
ap = AwesomePrint.new(options)
|
10
|
+
ap.puts object
|
11
|
+
end
|
12
|
+
|
13
|
+
module_function :ap
|
14
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Copyright (c) 2010 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Awesome Print is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
class String # :nodoc:
|
7
|
+
|
8
|
+
[ :gray, :red, :green, :yellow, :blue, :purple, :cyan, :white ].each_with_index do |color, i|
|
9
|
+
if STDOUT.tty? && ENV['TERM'] && ENV['TERM'] != 'dumb'
|
10
|
+
define_method color do "\033[1;#{30+i}m#{self}\033[0m" end
|
11
|
+
define_method :"#{color}ish" do "\033[0;#{30+i}m#{self}\033[0m" end
|
12
|
+
else
|
13
|
+
define_method color do self end
|
14
|
+
alias :"#{color}ish" color # <- This break Rdoc: Name or symbol expected (got #<RubyToken::TkDSTRING
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
alias :black :grayish
|
19
|
+
alias :pale :whiteish
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# Copyright (c) 2010 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Awesome Print is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
module AwesomePrintRails
|
7
|
+
|
8
|
+
def self.included(base)
|
9
|
+
base.alias_method_chain :printable, :rails
|
10
|
+
end
|
11
|
+
|
12
|
+
# Add ActiveRecord class names to the dispatcher pipeline.
|
13
|
+
#------------------------------------------------------------------------------
|
14
|
+
def printable_with_rails(object)
|
15
|
+
printable = printable_without_rails(object)
|
16
|
+
if printable == :self
|
17
|
+
if object.is_a?(ActiveRecord::Base)
|
18
|
+
printable = :active_record_instance
|
19
|
+
elsif object.is_a?(ActiveSupport::TimeWithZone)
|
20
|
+
printable = :active_support_time
|
21
|
+
end
|
22
|
+
elsif printable == :class && object.class.is_a?(ActiveRecord::Base.class)
|
23
|
+
printable = :active_record_class
|
24
|
+
end
|
25
|
+
printable
|
26
|
+
end
|
27
|
+
|
28
|
+
# Format ActiveRecord instance object.
|
29
|
+
#------------------------------------------------------------------------------
|
30
|
+
def awesome_active_record_instance(object)
|
31
|
+
data = object.class.column_names.inject(ActiveSupport::OrderedHash.new) do |hash, name|
|
32
|
+
hash[name.to_sym] = object.send(name) if object.has_attribute?(name) || object.new_record?
|
33
|
+
hash
|
34
|
+
end
|
35
|
+
"#{object} " + awesome_hash(data)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Format ActiveRecord class object.
|
39
|
+
#------------------------------------------------------------------------------
|
40
|
+
def awesome_active_record_class(object)
|
41
|
+
if object.table_exists?
|
42
|
+
data = object.columns.inject(ActiveSupport::OrderedHash.new) do |hash, c|
|
43
|
+
hash[c.name.to_sym] = c.type
|
44
|
+
hash
|
45
|
+
end
|
46
|
+
"class #{object} < #{object.superclass} " << awesome_hash(data)
|
47
|
+
else
|
48
|
+
object.inspect
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Format ActiveSupport::TimeWithZone as standard Time.
|
53
|
+
#------------------------------------------------------------------------------
|
54
|
+
def awesome_active_support_time(object)
|
55
|
+
awesome_self(object, :as => :time)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
AwesomePrint.send(:include, AwesomePrintRails)
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "..", "init")
|
@@ -0,0 +1,261 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "AwesomePrint" do
|
4
|
+
before(:each) do
|
5
|
+
@color_ap = AwesomePrint.new
|
6
|
+
@plain_ap = AwesomePrint.new(:plain => true)
|
7
|
+
end
|
8
|
+
|
9
|
+
#------------------------------------------------------------------------------
|
10
|
+
describe "Array" do
|
11
|
+
before(:each) do
|
12
|
+
@arr = [ 1, :two, "three", [ nil, [ true, false] ] ]
|
13
|
+
end
|
14
|
+
|
15
|
+
it "plain multiline" do
|
16
|
+
ap = AwesomePrint.new(:plain => true)
|
17
|
+
ap.send(:awesome, @arr).should == <<-EOS.strip
|
18
|
+
[
|
19
|
+
[0] 1,
|
20
|
+
[1] :two,
|
21
|
+
[2] "three",
|
22
|
+
[3] [
|
23
|
+
[0] nil,
|
24
|
+
[1] [
|
25
|
+
[0] true,
|
26
|
+
[1] false
|
27
|
+
]
|
28
|
+
]
|
29
|
+
]
|
30
|
+
EOS
|
31
|
+
end
|
32
|
+
|
33
|
+
it "plain multiline indented" do
|
34
|
+
ap = AwesomePrint.new(:plain => true, :indent => 2)
|
35
|
+
ap.send(:awesome, @arr).should == <<-EOS.strip
|
36
|
+
[
|
37
|
+
[0] 1,
|
38
|
+
[1] :two,
|
39
|
+
[2] "three",
|
40
|
+
[3] [
|
41
|
+
[0] nil,
|
42
|
+
[1] [
|
43
|
+
[0] true,
|
44
|
+
[1] false
|
45
|
+
]
|
46
|
+
]
|
47
|
+
]
|
48
|
+
EOS
|
49
|
+
end
|
50
|
+
|
51
|
+
it "plain single line" do
|
52
|
+
ap = AwesomePrint.new(:plain => true, :multiline => false)
|
53
|
+
ap.send(:awesome, @arr).should == '[ 1, :two, "three", [ nil, [ true, false ] ] ]'
|
54
|
+
end
|
55
|
+
|
56
|
+
it "colored multiline" do
|
57
|
+
ap = AwesomePrint.new
|
58
|
+
ap.send(:awesome, @arr).should == <<-EOS.strip
|
59
|
+
[
|
60
|
+
\e[1;37m [0] \e[0m\e[1;34m1\e[0m,
|
61
|
+
\e[1;37m [1] \e[0m\e[0;36m:two\e[0m,
|
62
|
+
\e[1;37m [2] \e[0m\e[0;33m\"three\"\e[0m,
|
63
|
+
\e[1;37m [3] \e[0m[
|
64
|
+
\e[1;37m [0] \e[0m\e[1;31mnil\e[0m,
|
65
|
+
\e[1;37m [1] \e[0m[
|
66
|
+
\e[1;37m [0] \e[0m\e[1;32mtrue\e[0m,
|
67
|
+
\e[1;37m [1] \e[0m\e[1;31mfalse\e[0m
|
68
|
+
]
|
69
|
+
]
|
70
|
+
]
|
71
|
+
EOS
|
72
|
+
end
|
73
|
+
|
74
|
+
it "colored multiline indented" do
|
75
|
+
ap = AwesomePrint.new(:indent => 8)
|
76
|
+
ap.send(:awesome, @arr).should == <<-EOS.strip
|
77
|
+
[
|
78
|
+
\e[1;37m [0] \e[0m\e[1;34m1\e[0m,
|
79
|
+
\e[1;37m [1] \e[0m\e[0;36m:two\e[0m,
|
80
|
+
\e[1;37m [2] \e[0m\e[0;33m\"three\"\e[0m,
|
81
|
+
\e[1;37m [3] \e[0m[
|
82
|
+
\e[1;37m [0] \e[0m\e[1;31mnil\e[0m,
|
83
|
+
\e[1;37m [1] \e[0m[
|
84
|
+
\e[1;37m [0] \e[0m\e[1;32mtrue\e[0m,
|
85
|
+
\e[1;37m [1] \e[0m\e[1;31mfalse\e[0m
|
86
|
+
]
|
87
|
+
]
|
88
|
+
]
|
89
|
+
EOS
|
90
|
+
end
|
91
|
+
|
92
|
+
it "colored single line" do
|
93
|
+
ap = AwesomePrint.new(:multiline => false)
|
94
|
+
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 ] ] ]"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
#------------------------------------------------------------------------------
|
99
|
+
describe "Nested Array" do
|
100
|
+
before(:each) do
|
101
|
+
@arr = [ 1, 2 ]
|
102
|
+
@arr << @arr
|
103
|
+
end
|
104
|
+
|
105
|
+
it "plain multiline" do
|
106
|
+
ap = AwesomePrint.new(:plain => true)
|
107
|
+
ap.send(:awesome, @arr).should == <<-EOS.strip
|
108
|
+
[
|
109
|
+
[0] 1,
|
110
|
+
[1] 2,
|
111
|
+
[2] [...]
|
112
|
+
]
|
113
|
+
EOS
|
114
|
+
end
|
115
|
+
|
116
|
+
it "plain single line" do
|
117
|
+
ap = AwesomePrint.new(:plain => true, :multiline => false)
|
118
|
+
ap.send(:awesome, @arr).should == "[ 1, 2, [...] ]"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
#------------------------------------------------------------------------------
|
123
|
+
describe "Hash" do
|
124
|
+
before(:each) do
|
125
|
+
@hash = { 1 => { :sym => { "str" => { [1, 2, 3] => { { :k => :v } => Hash } } } } }
|
126
|
+
end
|
127
|
+
|
128
|
+
it "plain multiline" do
|
129
|
+
ap = AwesomePrint.new(:plain => true)
|
130
|
+
ap.send(:awesome, @hash).should == <<-EOS.strip
|
131
|
+
{
|
132
|
+
1 => {
|
133
|
+
:sym => {
|
134
|
+
"str" => {
|
135
|
+
[ 1, 2, 3 ] => {
|
136
|
+
{ :k => :v } => Hash < Object
|
137
|
+
}
|
138
|
+
}
|
139
|
+
}
|
140
|
+
}
|
141
|
+
}
|
142
|
+
EOS
|
143
|
+
end
|
144
|
+
|
145
|
+
it "plain multiline indented" do
|
146
|
+
ap = AwesomePrint.new(:plain => true, :indent => 1)
|
147
|
+
ap.send(:awesome, @hash).should == <<-EOS.strip
|
148
|
+
{
|
149
|
+
1 => {
|
150
|
+
:sym => {
|
151
|
+
"str" => {
|
152
|
+
[ 1, 2, 3 ] => {
|
153
|
+
{ :k => :v } => Hash < Object
|
154
|
+
}
|
155
|
+
}
|
156
|
+
}
|
157
|
+
}
|
158
|
+
}
|
159
|
+
EOS
|
160
|
+
end
|
161
|
+
|
162
|
+
it "plain single line" do
|
163
|
+
ap = AwesomePrint.new(:plain => true, :multiline => false)
|
164
|
+
ap.send(:awesome, @hash).should == '{ 1 => { :sym => { "str" => { [ 1, 2, 3 ] => { { :k => :v } => Hash < Object } } } } }'
|
165
|
+
end
|
166
|
+
|
167
|
+
it "colored multiline" do
|
168
|
+
ap = AwesomePrint.new
|
169
|
+
ap.send(:awesome, @hash).should == <<-EOS.strip
|
170
|
+
{
|
171
|
+
1\e[1;30m => \e[0m{
|
172
|
+
:sym\e[1;30m => \e[0m{
|
173
|
+
\"str\"\e[1;30m => \e[0m{
|
174
|
+
[ 1, 2, 3 ]\e[1;30m => \e[0m{
|
175
|
+
{ :k => :v }\e[1;30m => \e[0m\e[1;33mHash < Object\e[0m
|
176
|
+
}
|
177
|
+
}
|
178
|
+
}
|
179
|
+
}
|
180
|
+
}
|
181
|
+
EOS
|
182
|
+
end
|
183
|
+
|
184
|
+
it "colored multiline indented" do
|
185
|
+
ap = AwesomePrint.new(:indent => 2)
|
186
|
+
ap.send(:awesome, @hash).should == <<-EOS.strip
|
187
|
+
{
|
188
|
+
1\e[1;30m => \e[0m{
|
189
|
+
:sym\e[1;30m => \e[0m{
|
190
|
+
\"str\"\e[1;30m => \e[0m{
|
191
|
+
[ 1, 2, 3 ]\e[1;30m => \e[0m{
|
192
|
+
{ :k => :v }\e[1;30m => \e[0m\e[1;33mHash < Object\e[0m
|
193
|
+
}
|
194
|
+
}
|
195
|
+
}
|
196
|
+
}
|
197
|
+
}
|
198
|
+
EOS
|
199
|
+
end
|
200
|
+
|
201
|
+
it "colored single line" do
|
202
|
+
ap = AwesomePrint.new(:multiline => false)
|
203
|
+
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 } } } } }"
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
|
208
|
+
#------------------------------------------------------------------------------
|
209
|
+
describe "Nested Hash" do
|
210
|
+
before(:each) do
|
211
|
+
@hash = {}
|
212
|
+
@hash[:a] = @hash
|
213
|
+
end
|
214
|
+
|
215
|
+
it "plain multiline" do
|
216
|
+
ap = AwesomePrint.new(:plain => true)
|
217
|
+
ap.send(:awesome, @hash).should == <<-EOS.strip
|
218
|
+
{
|
219
|
+
:a => {...}
|
220
|
+
}
|
221
|
+
EOS
|
222
|
+
end
|
223
|
+
|
224
|
+
it "plain single line" do
|
225
|
+
ap = AwesomePrint.new(:plain => true, :multiline => false)
|
226
|
+
ap.send(:awesome, @hash).should == '{ :a => {...} }'
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
#------------------------------------------------------------------------------
|
231
|
+
describe "Class" do
|
232
|
+
it "shoud show superclass (plain)" do
|
233
|
+
ap = AwesomePrint.new(:plain => true)
|
234
|
+
ap.send(:awesome, self.class).should == "#{self.class} < #{self.class.superclass}"
|
235
|
+
end
|
236
|
+
|
237
|
+
it "shoud show superclass (color)" do
|
238
|
+
ap = AwesomePrint.new
|
239
|
+
ap.send(:awesome_class, self.class).should == "#{self.class} < #{self.class.superclass}".yellow
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
#------------------------------------------------------------------------------
|
244
|
+
describe "File" do
|
245
|
+
it "should display a file (plain)" do
|
246
|
+
File.open(__FILE__, "r") do |f|
|
247
|
+
@plain_ap.send(:awesome_file, f).should == "#{f.inspect}\n" << `ls -alF #{f.path}`.chop
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
#------------------------------------------------------------------------------
|
253
|
+
describe "Dir" do
|
254
|
+
it "should display a direcory (plain)" do
|
255
|
+
Dir.open(File.dirname(__FILE__)) do |d|
|
256
|
+
@plain_ap.send(:awesome_dir, d).should == "#{d.inspect}\n" << `ls -alF #{d.path}`.chop
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
end
|
data/spec/rails_spec.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
if defined?(::Rails)
|
4
|
+
|
5
|
+
# Create tableless ActiveRecord model.
|
6
|
+
#------------------------------------------------------------------------------
|
7
|
+
class User < ActiveRecord::Base
|
8
|
+
def self.columns()
|
9
|
+
@columns ||= []
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.column(name, sql_type = nil, default = nil, null = true)
|
13
|
+
columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.table_exists?
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
column :id, :integer
|
21
|
+
column :name, :string
|
22
|
+
column :rank, :integer
|
23
|
+
column :admin, :boolean
|
24
|
+
column :created_at, :datetime
|
25
|
+
end
|
26
|
+
|
27
|
+
#------------------------------------------------------------------------------
|
28
|
+
describe "ActiveRecord instance" do
|
29
|
+
before(:each) do
|
30
|
+
@diana = User.new(:name => "Diana", :rank => 1, :admin => false, :created_at => "1992-10-10 12:30:00")
|
31
|
+
@laura = User.new(:name => "Laura", :rank => 2, :admin => true, :created_at => "2003-05-26 14:15:00")
|
32
|
+
@ap = AwesomePrint.new(:plain => true)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "display single record" do
|
36
|
+
out = @ap.send(:awesome, @diana)
|
37
|
+
out.gsub(/0x([a-f\d]+)/, "0x01234567").should == <<-EOS.strip
|
38
|
+
#<User:0x01234567> {
|
39
|
+
:id => nil,
|
40
|
+
:name => "Diana",
|
41
|
+
:rank => 1,
|
42
|
+
:admin => false,
|
43
|
+
:created_at => Sat, 10 Oct 1992 12:30:00 UTC +00:00
|
44
|
+
}
|
45
|
+
EOS
|
46
|
+
end
|
47
|
+
|
48
|
+
it "display multiple records" do
|
49
|
+
out = @ap.send(:awesome, [ @diana, @laura ])
|
50
|
+
out.gsub(/0x([a-f\d]+)/, "0x01234567").should == <<-EOS.strip
|
51
|
+
[
|
52
|
+
[0] #<User:0x01234567> {
|
53
|
+
:id => nil,
|
54
|
+
:name => "Diana",
|
55
|
+
:rank => 1,
|
56
|
+
:admin => false,
|
57
|
+
:created_at => Sat, 10 Oct 1992 12:30:00 UTC +00:00
|
58
|
+
},
|
59
|
+
[1] #<User:0x01234567> {
|
60
|
+
:id => nil,
|
61
|
+
:name => "Laura",
|
62
|
+
:rank => 2,
|
63
|
+
:admin => true,
|
64
|
+
:created_at => Mon, 26 May 2003 14:15:00 UTC +00:00
|
65
|
+
}
|
66
|
+
]
|
67
|
+
EOS
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
#------------------------------------------------------------------------------
|
72
|
+
describe "ActiveRecord class" do
|
73
|
+
it "should" do
|
74
|
+
@ap = AwesomePrint.new(:plain => true)
|
75
|
+
@ap.send(:awesome, User).should == <<-EOS.strip
|
76
|
+
class User < ActiveRecord::Base {
|
77
|
+
:id => :integer,
|
78
|
+
:name => :string,
|
79
|
+
:rank => :integer,
|
80
|
+
:admin => :boolean,
|
81
|
+
:created_at => :datetime
|
82
|
+
}
|
83
|
+
EOS
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
data/spec/string_spec.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "String extensions" do
|
4
|
+
[ :gray, :red, :green, :yellow, :blue, :purple, :cyan, :white ].each_with_index do |color, i|
|
5
|
+
it "should have #{color} color" do
|
6
|
+
color.to_s.send(color).should == "\033[1;#{30+i}m#{color}\033[0m"
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should have #{color}ish color" do
|
10
|
+
color.to_s.send(:"#{color}ish").should == "\033[0;#{30+i}m#{color}\033[0m"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have black and pale colors" do
|
15
|
+
"black".send(:black).should == "black".send(:grayish)
|
16
|
+
"pale".send(:pale).should == "pale".send(:whiteish)
|
17
|
+
end
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: awesome_print
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Michael Dvorkin
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-04-02 00:00:00 -07:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 1
|
29
|
+
- 2
|
30
|
+
- 9
|
31
|
+
version: 1.2.9
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
description: "Great Ruby dubugging companion: pretty print Ruby objects to visualize their structure. Supports Rails ActiveRecord objects via included mixin."
|
35
|
+
email: mike@dvorkin.net
|
36
|
+
executables: []
|
37
|
+
|
38
|
+
extensions: []
|
39
|
+
|
40
|
+
extra_rdoc_files:
|
41
|
+
- LICENSE
|
42
|
+
- README.md
|
43
|
+
files:
|
44
|
+
- LICENSE
|
45
|
+
- README.md
|
46
|
+
- Rakefile
|
47
|
+
- VERSION
|
48
|
+
- init.rb
|
49
|
+
- lib/ap.rb
|
50
|
+
- lib/ap/awesome_print.rb
|
51
|
+
- lib/ap/core_ext/kernel.rb
|
52
|
+
- lib/ap/core_ext/string.rb
|
53
|
+
- lib/ap/mixin/rails.rb
|
54
|
+
- rails/init.rb
|
55
|
+
- spec/awesome_print_spec.rb
|
56
|
+
- spec/rails_spec.rb
|
57
|
+
- spec/spec.opts
|
58
|
+
- spec/spec_helper.rb
|
59
|
+
- spec/string_spec.rb
|
60
|
+
has_rdoc: true
|
61
|
+
homepage: http://github.com/michaeldv/awesome_print
|
62
|
+
licenses: []
|
63
|
+
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options:
|
66
|
+
- --charset=UTF-8
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
version: "0"
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project: awesome_print
|
86
|
+
rubygems_version: 1.3.6
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Pretty print Ruby objects with proper indentation and colors.
|
90
|
+
test_files:
|
91
|
+
- spec/awesome_print_spec.rb
|
92
|
+
- spec/rails_spec.rb
|
93
|
+
- spec/spec_helper.rb
|
94
|
+
- spec/string_spec.rb
|