awesome_print 0.2.1 → 0.3.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/CHANGELOG +7 -0
- data/README.md +64 -6
- data/Rakefile +28 -10
- data/VERSION +1 -1
- data/lib/ap.rb +3 -0
- data/lib/ap/awesome_print.rb +95 -17
- data/lib/ap/core_ext/array.rb +67 -0
- data/lib/ap/core_ext/class.rb +15 -0
- data/lib/ap/core_ext/object.rb +17 -0
- data/lib/awesome_print.rb +25 -0
- data/spec/active_record_spec.rb +21 -5
- data/spec/awesome_print_spec.rb +115 -0
- data/spec/methods_spec.rb +409 -0
- data/spec/spec_helper.rb +18 -4
- metadata +13 -8
- data/spec/spec.opts +0 -1
data/CHANGELOG
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
0.3.0
|
2
|
+
- Display object.methods and family in human readable format
|
3
|
+
- Objects inherited from Array, Hash, File, Dir, and Struct are shown as their base class
|
4
|
+
- Added option to suppress array index in output (Sean Gallagher)
|
5
|
+
- Updated README on how to set up ~/.irbrc for MacRuby (Eloy Duran)
|
6
|
+
- Specs pass 100% with Ruby 1.8.7/RSpec 1.3 and Ruby 1.9.2/RSpec 2.0
|
7
|
+
|
1
8
|
0.2.1
|
2
9
|
- ap can now be used within Rails templates (ex. <%= ap object %>)
|
3
10
|
- Added support for printing Struct
|
data/README.md
CHANGED
@@ -8,10 +8,10 @@ objects and usage within Rails templates are supported via included mixins.
|
|
8
8
|
$ gem install awesome_print
|
9
9
|
|
10
10
|
# Installing as Rails plugin
|
11
|
-
$ ruby script/plugin install http://github.com/michaeldv/
|
11
|
+
$ ruby script/plugin install http://github.com/michaeldv/awesome_print.git
|
12
12
|
|
13
13
|
# Cloning the repository
|
14
|
-
$ git clone git://github.com/michaeldv/
|
14
|
+
$ git clone git://github.com/michaeldv/awesome_print.git
|
15
15
|
|
16
16
|
### Usage ###
|
17
17
|
|
@@ -86,6 +86,47 @@ Supported color names:
|
|
86
86
|
$ ruby 3.rb
|
87
87
|
[ false, 42, [ "forty", "two" ], [...] ]
|
88
88
|
|
89
|
+
$ cat > 4.rb
|
90
|
+
require "ap"
|
91
|
+
class Hello
|
92
|
+
def self.world(x, y, z = nil, &blk)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
ap Hello.methods - Class.methods
|
96
|
+
^D
|
97
|
+
$ ruby 4.rb
|
98
|
+
[
|
99
|
+
[0] world(x, y, *z, &blk) Hello
|
100
|
+
]
|
101
|
+
|
102
|
+
$ cat > 5.rb
|
103
|
+
require "ap"
|
104
|
+
ap (''.methods - Object.methods).grep(/!/)
|
105
|
+
^D
|
106
|
+
$ ruby 5.rb
|
107
|
+
[
|
108
|
+
[ 0] capitalize!() String
|
109
|
+
[ 1] chomp!(*arg1) String
|
110
|
+
[ 2] chop!() String
|
111
|
+
[ 3] delete!(*arg1) String
|
112
|
+
[ 4] downcase!() String
|
113
|
+
[ 5] encode!(*arg1) String
|
114
|
+
[ 6] gsub!(*arg1) String
|
115
|
+
[ 7] lstrip!() String
|
116
|
+
[ 8] next!() String
|
117
|
+
[ 9] reverse!() String
|
118
|
+
[10] rstrip!() String
|
119
|
+
[11] slice!(*arg1) String
|
120
|
+
[12] squeeze!(*arg1) String
|
121
|
+
[13] strip!() String
|
122
|
+
[14] sub!(*arg1) String
|
123
|
+
[15] succ!() String
|
124
|
+
[16] swapcase!() String
|
125
|
+
[17] tr!(arg1, arg2) String
|
126
|
+
[18] tr_s!(arg1, arg2) String
|
127
|
+
[19] upcase!() String
|
128
|
+
]
|
129
|
+
|
89
130
|
### Example (Rails console) ###
|
90
131
|
$ ruby script/console
|
91
132
|
Loading development environment (Rails 2.3.5)
|
@@ -150,10 +191,19 @@ lines into your ~/.irbrc file:
|
|
150
191
|
|
151
192
|
require "rubygems"
|
152
193
|
require "ap"
|
153
|
-
|
154
|
-
|
155
|
-
|
194
|
+
|
195
|
+
unless IRB.version.include?('DietRB')
|
196
|
+
IRB::Irb.class_eval do
|
197
|
+
def output_value
|
198
|
+
ap @context.last_value
|
199
|
+
end
|
156
200
|
end
|
201
|
+
else # MacRuby
|
202
|
+
IRB.formatter = Class.new(IRB::Formatter) do
|
203
|
+
def inspect_object(object)
|
204
|
+
object.ai
|
205
|
+
end
|
206
|
+
end.new
|
157
207
|
end
|
158
208
|
|
159
209
|
### Logger Convenience Method ###
|
@@ -190,6 +240,12 @@ For example:
|
|
190
240
|
}
|
191
241
|
}
|
192
242
|
|
243
|
+
### Running Specs ###
|
244
|
+
|
245
|
+
$ rake spec # Entire spec suite.
|
246
|
+
$ ruby -rubygems spec/logger_spec.rb # Individual spec file (Ruby 1.8.7 and RSpec 1.3+)
|
247
|
+
$ rspec spec/logger_spec.rb # Individual spec file (Ruby 1.9.2 and RSpec 2.0+)
|
248
|
+
|
193
249
|
### Note on Patches/Pull Requests ###
|
194
250
|
* Fork the project on Github.
|
195
251
|
* Make your feature addition or bug fix.
|
@@ -200,7 +256,9 @@ For example:
|
|
200
256
|
### Contributors ###
|
201
257
|
|
202
258
|
* Daniel Bretoi -- http://github.com/danielb2
|
203
|
-
*
|
259
|
+
* Eloy Duran -- http://github.com/alloy
|
260
|
+
* Benoit Daloze -- http://github.com/eregon
|
261
|
+
* Sean Gallagher -- http://github.com/torandu
|
204
262
|
* Tobias Crawley -- http://github.com/tobias
|
205
263
|
|
206
264
|
### License ###
|
data/Rakefile
CHANGED
@@ -11,7 +11,11 @@ begin
|
|
11
11
|
gem.email = "mike@dvorkin.net"
|
12
12
|
gem.homepage = "http://github.com/michaeldv/awesome_print"
|
13
13
|
gem.authors = ["Michael Dvorkin"]
|
14
|
-
|
14
|
+
if RUBY_VERSION.to_f >= 1.9
|
15
|
+
gem.add_development_dependency "rspec", ">= 2.0.0"
|
16
|
+
else
|
17
|
+
gem.add_development_dependency "rspec", ">= 1.3.0"
|
18
|
+
end
|
15
19
|
gem.files = FileList["[A-Z]*", "lib/**/*.rb", "rails/*.rb", "spec/*", "init.rb"]
|
16
20
|
gem.has_rdoc = false
|
17
21
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
@@ -21,16 +25,30 @@ rescue LoadError
|
|
21
25
|
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
22
26
|
end
|
23
27
|
|
24
|
-
|
25
|
-
|
26
|
-
spec
|
27
|
-
|
28
|
-
|
28
|
+
if RUBY_VERSION.to_f >= 1.9
|
29
|
+
require "rspec/core/rake_task" # RSpec 2.0
|
30
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
31
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
32
|
+
spec.rspec_opts = ['--color']
|
33
|
+
end
|
34
|
+
|
35
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
36
|
+
spec.rcov = true
|
37
|
+
spec.rcov_opts = %q[--exclude "spec"]
|
38
|
+
end
|
39
|
+
else
|
40
|
+
require 'spec/rake/spectask'
|
41
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
42
|
+
spec.libs << 'lib' << 'spec'
|
43
|
+
spec.spec_opts = ['--color']
|
44
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
45
|
+
end
|
29
46
|
|
30
|
-
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
31
|
-
|
32
|
-
|
33
|
-
|
47
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
48
|
+
spec.libs << 'lib' << 'spec'
|
49
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
50
|
+
spec.rcov = true
|
51
|
+
end
|
34
52
|
end
|
35
53
|
|
36
54
|
task :spec => :check_dependencies
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/lib/ap.rb
CHANGED
@@ -3,7 +3,10 @@
|
|
3
3
|
# Awesome Print is freely distributable under the terms of MIT license.
|
4
4
|
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
5
|
#------------------------------------------------------------------------------
|
6
|
+
require File.dirname(__FILE__) + "/ap/core_ext/array"
|
6
7
|
require File.dirname(__FILE__) + "/ap/core_ext/string"
|
8
|
+
require File.dirname(__FILE__) + "/ap/core_ext/object"
|
9
|
+
require File.dirname(__FILE__) + "/ap/core_ext/class"
|
7
10
|
require File.dirname(__FILE__) + "/ap/core_ext/kernel"
|
8
11
|
require File.dirname(__FILE__) + "/ap/awesome_print"
|
9
12
|
|
data/lib/ap/awesome_print.rb
CHANGED
@@ -6,14 +6,15 @@
|
|
6
6
|
require "shellwords"
|
7
7
|
|
8
8
|
class AwesomePrint
|
9
|
-
AP = :__awesome_print__
|
10
|
-
CORE = [ :array, :hash, :class, :file, :dir, :bigdecimal, :rational, :struct ]
|
9
|
+
AP = :__awesome_print__ unless defined?(AwesomePrint::AP)
|
10
|
+
CORE = [ :array, :hash, :class, :file, :dir, :bigdecimal, :rational, :struct, :method, :unboundmethod ] unless defined?(AwesomePrint::CORE)
|
11
11
|
|
12
12
|
def initialize(options = {})
|
13
13
|
@options = {
|
14
14
|
:multiline => true,
|
15
15
|
:plain => false,
|
16
16
|
:indent => 4,
|
17
|
+
:index => true,
|
17
18
|
:color => {
|
18
19
|
:array => :white,
|
19
20
|
:bigdecimal => :blue,
|
@@ -28,7 +29,9 @@ class AwesomePrint
|
|
28
29
|
:string => :yellowish,
|
29
30
|
:symbol => :cyanish,
|
30
31
|
:time => :greenish,
|
31
|
-
:trueclass => :green
|
32
|
+
:trueclass => :green,
|
33
|
+
:method => :purpleish,
|
34
|
+
:args => :pale
|
32
35
|
}
|
33
36
|
}
|
34
37
|
|
@@ -47,18 +50,23 @@ class AwesomePrint
|
|
47
50
|
def awesome_array(a)
|
48
51
|
return "[]" if a == []
|
49
52
|
|
50
|
-
if @
|
53
|
+
if a.instance_variable_defined?('@__awesome_methods__')
|
54
|
+
methods_array(a)
|
55
|
+
elsif @options[:multiline]
|
51
56
|
width = (a.size - 1).to_s.size
|
52
57
|
data = a.inject([]) do |arr, item|
|
53
|
-
index =
|
58
|
+
index = if @options[:index]
|
59
|
+
colorize("#{indent}[#{arr.size.to_s.rjust(width)}] ", :array)
|
60
|
+
else
|
61
|
+
colorize(indent, :array)
|
62
|
+
end
|
54
63
|
indented do
|
55
64
|
arr << (index << awesome(item))
|
56
65
|
end
|
57
66
|
end
|
58
67
|
"[\n" << data.join(",\n") << "\n#{outdent}]"
|
59
68
|
else
|
60
|
-
|
61
|
-
"[ #{data.join(', ')} ]"
|
69
|
+
"[ " << a.map{ |item| awesome(item) }.join(", ") << " ]"
|
62
70
|
end
|
63
71
|
end
|
64
72
|
|
@@ -67,23 +75,23 @@ class AwesomePrint
|
|
67
75
|
def awesome_hash(h)
|
68
76
|
return "{}" if h == {}
|
69
77
|
|
70
|
-
data = h.keys.
|
78
|
+
data = h.keys.map do |key|
|
71
79
|
plain_single_line do
|
72
|
-
|
80
|
+
[ awesome(key), h[key] ]
|
73
81
|
end
|
74
82
|
end
|
75
83
|
|
76
84
|
width = data.map { |key, | key.size }.max || 0
|
77
85
|
width += @indentation if @options[:indent] > 0
|
78
86
|
|
79
|
-
data = data.
|
87
|
+
data = data.map do |key, value|
|
80
88
|
if @options[:multiline]
|
81
89
|
formatted_key = (@options[:indent] >= 0 ? key.rjust(width) : indent + key.ljust(width))
|
82
90
|
else
|
83
91
|
formatted_key = key
|
84
92
|
end
|
85
93
|
indented do
|
86
|
-
|
94
|
+
formatted_key << colorize(" => ", :hash) << awesome(value)
|
87
95
|
end
|
88
96
|
end
|
89
97
|
if @options[:multiline]
|
@@ -132,10 +140,18 @@ class AwesomePrint
|
|
132
140
|
end
|
133
141
|
alias :awesome_rational :awesome_bigdecimal
|
134
142
|
|
143
|
+
# Format a method.
|
144
|
+
#------------------------------------------------------------------------------
|
145
|
+
def awesome_method(m)
|
146
|
+
name, args, owner = method_tuple(m)
|
147
|
+
"#{colorize(owner, :class)}##{colorize(name, :method)}#{colorize(args, :args)}"
|
148
|
+
end
|
149
|
+
alias :awesome_unboundmethod :awesome_method
|
150
|
+
|
135
151
|
# Catch all method to format an arbitrary object.
|
136
152
|
#------------------------------------------------------------------------------
|
137
153
|
def awesome_self(object, appear = {})
|
138
|
-
colorize(object.inspect << appear[:with].to_s, appear[:as] || declassify(object))
|
154
|
+
colorize(object.inspect.to_s << appear[:with].to_s, appear[:as] || declassify(object))
|
139
155
|
end
|
140
156
|
|
141
157
|
# Dispatcher that detects data nesting and invokes object-aware formatter.
|
@@ -153,6 +169,38 @@ class AwesomePrint
|
|
153
169
|
end
|
154
170
|
end
|
155
171
|
|
172
|
+
# Format object.methods array.
|
173
|
+
#------------------------------------------------------------------------------
|
174
|
+
def methods_array(a)
|
175
|
+
object = a.instance_variable_get('@__awesome_methods__')
|
176
|
+
tuples = a.map do |name|
|
177
|
+
if object.respond_to?(name, true) # Regular method?
|
178
|
+
method_tuple(object.method(name))
|
179
|
+
elsif object.respond_to?(:instance_method) # Unbound method?
|
180
|
+
method_tuple(object.instance_method(name))
|
181
|
+
else # WTF method.
|
182
|
+
[ name.to_s, '(?)', '' ]
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
width = (tuples.size - 1).to_s.size
|
187
|
+
name_width = tuples.map { |item| item[0].size }.max || 0
|
188
|
+
args_width = tuples.map { |item| item[1].size }.max || 0
|
189
|
+
|
190
|
+
data = tuples.inject([]) do |arr, item|
|
191
|
+
index = if @options[:index]
|
192
|
+
"#{indent}[#{arr.size.to_s.rjust(width)}]"
|
193
|
+
else
|
194
|
+
indent
|
195
|
+
end
|
196
|
+
indented do
|
197
|
+
arr << "#{index} #{colorize(item[0].rjust(name_width), :method)}#{colorize(item[1].ljust(args_width), :args)} #{colorize(item[2], :class)}"
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
"[\n" << data.join("\n") << "\n#{outdent}]"
|
202
|
+
end
|
203
|
+
|
156
204
|
# Format nested data, for example:
|
157
205
|
# arr = [1, 2]; arr << arr
|
158
206
|
# => [1,2, [...]]
|
@@ -174,13 +222,17 @@ class AwesomePrint
|
|
174
222
|
CORE.grep(declassify(object))[0] || :self
|
175
223
|
end
|
176
224
|
|
177
|
-
# Turn class name into symbol, ex: Hello::World => :hello_world.
|
225
|
+
# Turn class name into symbol, ex: Hello::World => :hello_world. Classes that
|
226
|
+
# inherit from Array, Hash, File, Dir, and Struct are treated as the base class.
|
178
227
|
#------------------------------------------------------------------------------
|
179
228
|
def declassify(object)
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
229
|
+
case object
|
230
|
+
when Array then :array
|
231
|
+
when Hash then :hash
|
232
|
+
when File then :file
|
233
|
+
when Dir then :dir
|
234
|
+
when Struct then :struct
|
235
|
+
else object.class.to_s.gsub(/:+/, "_").downcase.to_sym
|
184
236
|
end
|
185
237
|
end
|
186
238
|
|
@@ -194,6 +246,32 @@ class AwesomePrint
|
|
194
246
|
end
|
195
247
|
end
|
196
248
|
|
249
|
+
# Return [ name, arguments, owner ] tuple for a given method.
|
250
|
+
#------------------------------------------------------------------------------
|
251
|
+
def method_tuple(method)
|
252
|
+
if method.respond_to?(:parameters) # Ruby 1.9.2+
|
253
|
+
# See http://ruby.runpaint.org/methods#method-objects-parameters
|
254
|
+
args = method.parameters.inject([]) do |arr, (type, name)|
|
255
|
+
name ||= (type == :block ? 'block' : "arg#{arr.size + 1}")
|
256
|
+
arr << case type
|
257
|
+
when :req then name.to_s
|
258
|
+
when :opt, :rest then "*#{name}"
|
259
|
+
when :block then "&#{name}"
|
260
|
+
else '?'
|
261
|
+
end
|
262
|
+
end
|
263
|
+
else # See http://ruby-doc.org/core/classes/Method.html#M001902
|
264
|
+
args = method.arity.abs.times.map { |i| "arg#{i+1}" }
|
265
|
+
args[-1] = "*#{args[-1]}" if method.arity < 0
|
266
|
+
end
|
267
|
+
|
268
|
+
if method.to_s =~ /(Unbound)*Method: (.*?)[#\.]/
|
269
|
+
owner = "#{$2}#{$1 ? '(unbound)' : ''}".gsub('(', ' (')
|
270
|
+
end
|
271
|
+
|
272
|
+
[ method.name.to_s, "(#{args.join(', ')})", owner.to_s ]
|
273
|
+
end
|
274
|
+
|
197
275
|
# Format hash keys as plain string regardless of underlying data type.
|
198
276
|
#------------------------------------------------------------------------------
|
199
277
|
def plain_single_line
|
@@ -0,0 +1,67 @@
|
|
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
|
+
#
|
7
|
+
# The following makes it possible to invoke awesome_print while performing
|
8
|
+
# operations on method arrays, ex:
|
9
|
+
#
|
10
|
+
# ap [].methods - Object.methods
|
11
|
+
# ap ''.methods.grep(/!|\?/)
|
12
|
+
#
|
13
|
+
# If you could think of a better way please let me know: twitter.com/mid :-)
|
14
|
+
#
|
15
|
+
class Array #:nodoc:
|
16
|
+
[ :-, :& ].each do |operator|
|
17
|
+
alias :"original_#{operator.object_id}" :"#{operator}"
|
18
|
+
define_method operator do |*args|
|
19
|
+
arr = self.send(:"original_#{operator.object_id}", *args)
|
20
|
+
if self.instance_variable_defined?('@__awesome_methods__')
|
21
|
+
arr.instance_variable_set('@__awesome_methods__', self.instance_variable_get('@__awesome_methods__'))
|
22
|
+
arr.sort!
|
23
|
+
end
|
24
|
+
arr
|
25
|
+
end
|
26
|
+
end
|
27
|
+
#
|
28
|
+
# Intercepting Array#grep needs a special treatment since grep accepts
|
29
|
+
# an optional block.
|
30
|
+
#
|
31
|
+
alias :original_grep :grep
|
32
|
+
def grep(pattern, &blk)
|
33
|
+
#
|
34
|
+
# The following looks rather insane and I've sent numerous hours trying
|
35
|
+
# to figure it out. The problem is that if grep gets called with the
|
36
|
+
# block, for example:
|
37
|
+
#
|
38
|
+
# [].methods.grep(/(.+?)_by/) { $1.to_sym }
|
39
|
+
#
|
40
|
+
# ...then simple:
|
41
|
+
#
|
42
|
+
# original_grep(pattern, &blk)
|
43
|
+
#
|
44
|
+
# doesn't set $1 within the grep block which causes nil.to_sym failure.
|
45
|
+
# The workaround below has been tested with Ruby 1.8.7/Rails 2.3.8 and
|
46
|
+
# Ruby 1.9.2/Rails 3.0.0. For more info see the following thread dating
|
47
|
+
# back to 1993 when Ruby 1.8.0 was as fresh off the grill as Ruby 1.9.2
|
48
|
+
# is in 2010 :-)
|
49
|
+
#
|
50
|
+
# http://www.justskins.com/forums/bug-when-rerouting-string-52852.html
|
51
|
+
#
|
52
|
+
# BTW, if you figure out a better way of intercepting Array#grep please
|
53
|
+
# let me know: twitter.com/mid -- or just say hi so I know you've read
|
54
|
+
# the comment :-)
|
55
|
+
#
|
56
|
+
arr = unless blk
|
57
|
+
original_grep(pattern)
|
58
|
+
else
|
59
|
+
original_grep(pattern) { |match| eval("%Q/#{match}/ =~ #{pattern.inspect}", blk.binding); yield match }
|
60
|
+
end
|
61
|
+
if self.instance_variable_defined?('@__awesome_methods__')
|
62
|
+
arr.instance_variable_set('@__awesome_methods__', self.instance_variable_get('@__awesome_methods__'))
|
63
|
+
arr.reject! { |item| !(item.is_a?(Symbol) || item.is_a?(String)) } # grep block might return crap.
|
64
|
+
end
|
65
|
+
arr
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,15 @@
|
|
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 Class #:nodoc:
|
7
|
+
methods.grep(/instance_methods$/) do |name|
|
8
|
+
alias :"original_#{name}" :"#{name}"
|
9
|
+
define_method name do |*args|
|
10
|
+
methods = self.send(:"original_#{name}", *args)
|
11
|
+
methods.instance_variable_set('@__awesome_methods__', self) # Evil?!
|
12
|
+
methods.sort!
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
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 Object #:nodoc:
|
7
|
+
methods.grep(/methods$/) do |name|
|
8
|
+
next if name.to_s.include? 'instance' # Instance methods are trapped in Class.
|
9
|
+
|
10
|
+
alias :"original_#{name}" :"#{name}"
|
11
|
+
define_method name do |*args|
|
12
|
+
methods = self.send(:"original_#{name}", *args)
|
13
|
+
methods.instance_variable_set('@__awesome_methods__', self) # Evil?!
|
14
|
+
methods.sort!
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,25 @@
|
|
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
|
+
#
|
7
|
+
# This is the copy of original 'ap.rb' file that matches the gem name. It makes
|
8
|
+
# it possible to omit the :require part in bundler's Gemfile:
|
9
|
+
#
|
10
|
+
# gem 'awesome_print', '>= 0.2.1', :require => 'ap'
|
11
|
+
# gem 'awesome_print', '>= 3.0.0'
|
12
|
+
#
|
13
|
+
require File.dirname(__FILE__) + "/ap/core_ext/array"
|
14
|
+
require File.dirname(__FILE__) + "/ap/core_ext/string"
|
15
|
+
require File.dirname(__FILE__) + "/ap/core_ext/object"
|
16
|
+
require File.dirname(__FILE__) + "/ap/core_ext/class"
|
17
|
+
require File.dirname(__FILE__) + "/ap/core_ext/kernel"
|
18
|
+
require File.dirname(__FILE__) + "/ap/awesome_print"
|
19
|
+
|
20
|
+
require File.dirname(__FILE__) + "/ap/core_ext/logger" if defined?(::Logger) or defined?(::ActiveSupport::BufferedLogger)
|
21
|
+
|
22
|
+
require File.dirname(__FILE__) + "/ap/mixin/action_view" if defined?(::ActionView)
|
23
|
+
require File.dirname(__FILE__) + "/ap/mixin/active_record" if defined?(::ActiveRecord)
|
24
|
+
require File.dirname(__FILE__) + "/ap/mixin/active_support" if defined?(::ActiveSupport)
|
25
|
+
|
data/spec/active_record_spec.rb
CHANGED
@@ -50,37 +50,53 @@ if defined?(::ActiveRecord)
|
|
50
50
|
|
51
51
|
it "display single record" do
|
52
52
|
out = @ap.send(:awesome, @diana)
|
53
|
-
|
53
|
+
str = <<-EOS.strip
|
54
54
|
#<User:0x01234567> {
|
55
55
|
:id => nil,
|
56
56
|
:name => "Diana",
|
57
57
|
:rank => 1,
|
58
58
|
:admin => false,
|
59
|
-
:created_at =>
|
59
|
+
:created_at => ?
|
60
60
|
}
|
61
61
|
EOS
|
62
|
+
if RUBY_VERSION.to_f < 1.9
|
63
|
+
str.sub!('?', 'Sat Oct 10 12:30:00 UTC 1992')
|
64
|
+
else
|
65
|
+
str.sub!('?', '1992-10-10 12:30:00 UTC')
|
66
|
+
end
|
67
|
+
|
68
|
+
out.gsub(/0x([a-f\d]+)/, "0x01234567").should == str
|
62
69
|
end
|
63
70
|
|
64
71
|
it "display multiple records" do
|
65
72
|
out = @ap.send(:awesome, [ @diana, @laura ])
|
66
|
-
|
73
|
+
str = <<-EOS.strip
|
67
74
|
[
|
68
75
|
[0] #<User:0x01234567> {
|
69
76
|
:id => nil,
|
70
77
|
:name => "Diana",
|
71
78
|
:rank => 1,
|
72
79
|
:admin => false,
|
73
|
-
:created_at =>
|
80
|
+
:created_at => ?
|
74
81
|
},
|
75
82
|
[1] #<User:0x01234567> {
|
76
83
|
:id => nil,
|
77
84
|
:name => "Laura",
|
78
85
|
:rank => 2,
|
79
86
|
:admin => true,
|
80
|
-
:created_at =>
|
87
|
+
:created_at => !
|
81
88
|
}
|
82
89
|
]
|
83
90
|
EOS
|
91
|
+
if RUBY_VERSION.to_f < 1.9
|
92
|
+
str.sub!('?', 'Sat Oct 10 12:30:00 UTC 1992')
|
93
|
+
str.sub!('!', 'Mon May 26 14:15:00 UTC 2003')
|
94
|
+
else
|
95
|
+
str.sub!('?', '1992-10-10 12:30:00 UTC')
|
96
|
+
str.sub!('!', '2003-05-26 14:15:00 UTC')
|
97
|
+
end
|
98
|
+
|
99
|
+
out.gsub(/0x([a-f\d]+)/, "0x01234567").should == str
|
84
100
|
end
|
85
101
|
end
|
86
102
|
|
data/spec/awesome_print_spec.rb
CHANGED
@@ -30,6 +30,23 @@ describe "AwesomePrint" do
|
|
30
30
|
]
|
31
31
|
]
|
32
32
|
]
|
33
|
+
EOS
|
34
|
+
end
|
35
|
+
|
36
|
+
it "plain multiline without index" do
|
37
|
+
@arr.ai(:plain => true, :index => false).should == <<-EOS.strip
|
38
|
+
[
|
39
|
+
1,
|
40
|
+
:two,
|
41
|
+
"three",
|
42
|
+
[
|
43
|
+
nil,
|
44
|
+
[
|
45
|
+
true,
|
46
|
+
false
|
47
|
+
]
|
48
|
+
]
|
49
|
+
]
|
33
50
|
EOS
|
34
51
|
end
|
35
52
|
|
@@ -50,6 +67,23 @@ EOS
|
|
50
67
|
EOS
|
51
68
|
end
|
52
69
|
|
70
|
+
it "plain multiline indented without index" do
|
71
|
+
@arr.ai(:plain => true, :indent => 2, :index => false).should == <<-EOS.strip
|
72
|
+
[
|
73
|
+
1,
|
74
|
+
:two,
|
75
|
+
"three",
|
76
|
+
[
|
77
|
+
nil,
|
78
|
+
[
|
79
|
+
true,
|
80
|
+
false
|
81
|
+
]
|
82
|
+
]
|
83
|
+
]
|
84
|
+
EOS
|
85
|
+
end
|
86
|
+
|
53
87
|
it "plain single line" do
|
54
88
|
@arr.ai(:plain => true, :multiline => false).should == '[ 1, :two, "three", [ nil, [ true, false ] ] ]'
|
55
89
|
end
|
@@ -110,6 +144,16 @@ EOS
|
|
110
144
|
EOS
|
111
145
|
end
|
112
146
|
|
147
|
+
it "plain multiline without index" do
|
148
|
+
@arr.ai(:plain => true, :index => false).should == <<-EOS.strip
|
149
|
+
[
|
150
|
+
1,
|
151
|
+
2,
|
152
|
+
[...]
|
153
|
+
]
|
154
|
+
EOS
|
155
|
+
end
|
156
|
+
|
113
157
|
it "plain single line" do
|
114
158
|
@arr.ai(:plain => true, :multiline => false).should == "[ 1, 2, [...] ]"
|
115
159
|
end
|
@@ -361,4 +405,75 @@ EOS
|
|
361
405
|
end
|
362
406
|
|
363
407
|
|
408
|
+
#------------------------------------------------------------------------------
|
409
|
+
describe "Misc" do
|
410
|
+
it "handle weird objects that return nil on inspect" do
|
411
|
+
weird = Class.new do
|
412
|
+
def inspect
|
413
|
+
nil
|
414
|
+
end
|
415
|
+
end
|
416
|
+
weird.new.ai(:plain => true).should == ''
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
#------------------------------------------------------------------------------
|
421
|
+
describe "Inherited from standard Ruby classes" do
|
422
|
+
after do
|
423
|
+
Object.instance_eval{ remove_const :My } if defined?(My)
|
424
|
+
end
|
425
|
+
|
426
|
+
it "inherited from Array should be displayed as Array" do
|
427
|
+
class My < Array; end
|
428
|
+
|
429
|
+
my = My.new([ 1, :two, "three", [ nil, [ true, false ] ] ])
|
430
|
+
my.ai(:plain => true).should == <<-EOS.strip
|
431
|
+
[
|
432
|
+
[0] 1,
|
433
|
+
[1] :two,
|
434
|
+
[2] "three",
|
435
|
+
[3] [
|
436
|
+
[0] nil,
|
437
|
+
[1] [
|
438
|
+
[0] true,
|
439
|
+
[1] false
|
440
|
+
]
|
441
|
+
]
|
442
|
+
]
|
443
|
+
EOS
|
444
|
+
end
|
445
|
+
|
446
|
+
it "inherited from Hash should be displayed as Hash" do
|
447
|
+
class My < Hash; end
|
448
|
+
|
449
|
+
my = My[ { 1 => { :sym => { "str" => { [1, 2, 3] => { { :k => :v } => Hash } } } } } ]
|
450
|
+
my.ai(:plain => true).should == <<-EOS.strip
|
451
|
+
{
|
452
|
+
1 => {
|
453
|
+
:sym => {
|
454
|
+
"str" => {
|
455
|
+
[ 1, 2, 3 ] => {
|
456
|
+
{ :k => :v } => Hash < Object
|
457
|
+
}
|
458
|
+
}
|
459
|
+
}
|
460
|
+
}
|
461
|
+
}
|
462
|
+
EOS
|
463
|
+
end
|
464
|
+
|
465
|
+
it "inherited from File should be displayed as File" do
|
466
|
+
class My < File; end
|
467
|
+
|
468
|
+
my = File.new('/dev/null')
|
469
|
+
my.ai(:plain => true).should == "#{my.inspect}\n" << `ls -alF #{my.path}`.chop
|
470
|
+
end
|
471
|
+
|
472
|
+
it "inherited from Dir should be displayed as Dir" do
|
473
|
+
class My < Dir; end
|
474
|
+
|
475
|
+
my = My.new('/tmp')
|
476
|
+
my.ai(:plain => true).should == "#{my.inspect}\n" << `ls -alF #{my.path}`.chop
|
477
|
+
end
|
478
|
+
end
|
364
479
|
end
|
@@ -0,0 +1,409 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "Single method" do
|
4
|
+
after do
|
5
|
+
Object.instance_eval{ remove_const :Hello } if defined?(Hello)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "plain: should handle a method with no arguments" do
|
9
|
+
method = ''.method(:upcase)
|
10
|
+
method.ai(:plain => true).should == 'String#upcase()'
|
11
|
+
end
|
12
|
+
|
13
|
+
it "color: should handle a method with no arguments" do
|
14
|
+
method = ''.method(:upcase)
|
15
|
+
method.ai.should == "\e[1;33mString\e[0m#\e[0;35mupcase\e[0m\e[0;37m()\e[0m"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "plain: should handle a method with one argument" do
|
19
|
+
method = ''.method(:include?)
|
20
|
+
method.ai(:plain => true).should == 'String#include?(arg1)'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "color: should handle a method with one argument" do
|
24
|
+
method = ''.method(:include?)
|
25
|
+
method.ai.should == "\e[1;33mString\e[0m#\e[0;35minclude?\e[0m\e[0;37m(arg1)\e[0m"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "plain: should handle a method with two arguments" do
|
29
|
+
method = ''.method(:tr)
|
30
|
+
method.ai(:plain => true).should == 'String#tr(arg1, arg2)'
|
31
|
+
end
|
32
|
+
|
33
|
+
it "color: should handle a method with two arguments" do
|
34
|
+
method = ''.method(:tr)
|
35
|
+
method.ai.should == "\e[1;33mString\e[0m#\e[0;35mtr\e[0m\e[0;37m(arg1, arg2)\e[0m"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "plain: should handle a method with multiple arguments" do
|
39
|
+
method = ''.method(:split)
|
40
|
+
method.ai(:plain => true).should == 'String#split(*arg1)'
|
41
|
+
end
|
42
|
+
|
43
|
+
it "color: should handle a method with multiple arguments" do
|
44
|
+
method = ''.method(:split)
|
45
|
+
method.ai.should == "\e[1;33mString\e[0m#\e[0;35msplit\e[0m\e[0;37m(*arg1)\e[0m"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "plain: should handle a method defined in mixin" do
|
49
|
+
method = ''.method(:is_a?)
|
50
|
+
method.ai(:plain => true).should == 'String (Kernel)#is_a?(arg1)'
|
51
|
+
end
|
52
|
+
|
53
|
+
it "color: should handle a method defined in mixin" do
|
54
|
+
method = ''.method(:is_a?)
|
55
|
+
method.ai.should == "\e[1;33mString (Kernel)\e[0m#\e[0;35mis_a?\e[0m\e[0;37m(arg1)\e[0m"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "plain: should handle an unbound method" do
|
59
|
+
class Hello
|
60
|
+
def world; end
|
61
|
+
end
|
62
|
+
method = Hello.instance_method(:world)
|
63
|
+
method.ai(:plain => true).should == 'Hello (unbound)#world()'
|
64
|
+
end
|
65
|
+
|
66
|
+
it "color: should handle an unbound method" do
|
67
|
+
class Hello
|
68
|
+
def world(a,b); end
|
69
|
+
end
|
70
|
+
method = Hello.instance_method(:world)
|
71
|
+
if RUBY_VERSION < '1.9.2'
|
72
|
+
method.ai.should == "\e[1;33mHello (unbound)\e[0m#\e[0;35mworld\e[0m\e[0;37m(arg1, arg2)\e[0m"
|
73
|
+
else
|
74
|
+
method.ai.should == "\e[1;33mHello (unbound)\e[0m#\e[0;35mworld\e[0m\e[0;37m(a, b)\e[0m"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "Object methods" do
|
80
|
+
after do
|
81
|
+
Object.instance_eval{ remove_const :Hello } if defined?(Hello)
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "object.methods" do
|
85
|
+
it "index: should handle object.methods" do
|
86
|
+
out = nil.methods.ai(:plain => true).split("\n").grep(/is_a\?/).first
|
87
|
+
out.should =~ /^\s+\[\s*\d+\]\s+is_a\?\(arg1\)\s+NilClass \(Kernel\)$/
|
88
|
+
end
|
89
|
+
|
90
|
+
it "no index: should handle object.methods" do
|
91
|
+
out = nil.methods.ai(:plain => true, :index => false).split("\n").grep(/is_a\?/).first
|
92
|
+
out.should =~ /^\s+is_a\?\(arg1\)\s+NilClass \(Kernel\)$/
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "object.public_methods" do
|
97
|
+
it "index: should handle object.public_methods" do
|
98
|
+
out = nil.public_methods.ai(:plain => true).split("\n").grep(/is_a\?/).first
|
99
|
+
out.should =~ /^\s+\[\s*\d+\]\s+is_a\?\(arg1\)\s+NilClass \(Kernel\)$/
|
100
|
+
end
|
101
|
+
|
102
|
+
it "no index: should handle object.public_methods" do
|
103
|
+
out = nil.public_methods.ai(:plain => true, :index => false).split("\n").grep(/is_a\?/).first
|
104
|
+
out.should =~ /^\s+is_a\?\(arg1\)\s+NilClass \(Kernel\)$/
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "object.private_methods" do
|
109
|
+
it "index: should handle object.private_methods" do
|
110
|
+
out = nil.private_methods.ai(:plain => true).split("\n").grep(/sleep/).first
|
111
|
+
out.should =~ /^\s+\[\s*\d+\]\s+sleep\(\*arg1\)\s+NilClass \(Kernel\)$/
|
112
|
+
end
|
113
|
+
|
114
|
+
it "no index: should handle object.private_methods" do
|
115
|
+
out = nil.private_methods.ai(:plain => true, :index => false).split("\n").grep(/sleep/).first
|
116
|
+
out.should =~ /^\s+sleep\(\*arg1\)\s+NilClass \(Kernel\)$/
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "object.protected_methods" do
|
121
|
+
it "index: should handle object.protected_methods" do
|
122
|
+
class Hello
|
123
|
+
protected
|
124
|
+
def m1; end
|
125
|
+
def m2; end
|
126
|
+
end
|
127
|
+
Hello.new.protected_methods.ai(:plain => true).should == "[\n [0] m1() Hello\n [1] m2() Hello\n]"
|
128
|
+
end
|
129
|
+
|
130
|
+
it "no index: should handle object.protected_methods" do
|
131
|
+
class Hello
|
132
|
+
protected
|
133
|
+
def m3(a,b); end
|
134
|
+
end
|
135
|
+
if RUBY_VERSION < '1.9.2'
|
136
|
+
Hello.new.protected_methods.ai(:plain => true, :index => false).should == "[\n m3(arg1, arg2) Hello\n]"
|
137
|
+
else
|
138
|
+
Hello.new.protected_methods.ai(:plain => true, :index => false).should == "[\n m3(a, b) Hello\n]"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "object.private_methods" do
|
144
|
+
it "index: should handle object.private_methods" do
|
145
|
+
class Hello
|
146
|
+
private
|
147
|
+
def m1; end
|
148
|
+
def m2; end
|
149
|
+
end
|
150
|
+
out = Hello.new.private_methods.ai(:plain => true).split("\n").grep(/m\d/)
|
151
|
+
out.first.should =~ /^\s+\[\d+\]\s+m1\(\)\s+Hello$/
|
152
|
+
out.last.should =~ /^\s+\[\d+\]\s+m2\(\)\s+Hello$/
|
153
|
+
end
|
154
|
+
|
155
|
+
it "no index: should handle object.private_methods" do
|
156
|
+
class Hello
|
157
|
+
private
|
158
|
+
def m3(a,b); end
|
159
|
+
end
|
160
|
+
out = Hello.new.private_methods.ai(:plain => true).split("\n").grep(/m\d/)
|
161
|
+
if RUBY_VERSION < '1.9.2'
|
162
|
+
out.first.should =~ /^\s+\[\d+\]\s+m3\(arg1, arg2\)\s+Hello$/
|
163
|
+
else
|
164
|
+
out.first.should =~ /^\s+\[\d+\]\s+m3\(a, b\)\s+Hello$/
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe "object.singleton_methods" do
|
170
|
+
it "index: should handle object.singleton_methods" do
|
171
|
+
class Hello
|
172
|
+
class << self
|
173
|
+
def m1; end
|
174
|
+
def m2; end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
out = Hello.singleton_methods.ai(:plain => true).split("\n").grep(/m\d/)
|
178
|
+
out.first.should =~ /^\s+\[\d+\]\s+m1\(\)\s+Hello$/
|
179
|
+
out.last.should =~ /^\s+\[\d+\]\s+m2\(\)\s+Hello$/
|
180
|
+
end
|
181
|
+
|
182
|
+
it "no index: should handle object.singleton_methods" do
|
183
|
+
class Hello
|
184
|
+
def self.m3(a,b); end
|
185
|
+
end
|
186
|
+
out = Hello.singleton_methods.ai(:plain => true, :index => false).split("\n").grep(/m\d/)
|
187
|
+
if RUBY_VERSION < '1.9.2'
|
188
|
+
out.first.should =~ /^\s+m3\(arg1, arg2\)\s+Hello$/
|
189
|
+
else
|
190
|
+
out.first.should =~ /^\s+m3\(a, b\)\s+Hello$/
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe "Class methods" do
|
197
|
+
after do
|
198
|
+
Object.instance_eval{ remove_const :Hello } if defined?(Hello)
|
199
|
+
end
|
200
|
+
|
201
|
+
describe "class.instance_methods" do
|
202
|
+
it "index: should handle unbound class.instance_methods" do
|
203
|
+
class Hello
|
204
|
+
def m1; end
|
205
|
+
def m2; end
|
206
|
+
end
|
207
|
+
out = Hello.instance_methods.ai(:plain => true).split("\n").grep(/m\d/)
|
208
|
+
out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(\)\s+Hello\s\(unbound\)$/
|
209
|
+
out.last.should =~ /^\s+\[\s*\d+\]\s+m2\(\)\s+Hello\s\(unbound\)$/
|
210
|
+
end
|
211
|
+
|
212
|
+
it "no index: should handle unbound class.instance_methods" do
|
213
|
+
class Hello
|
214
|
+
def m3(a,b); end
|
215
|
+
end
|
216
|
+
out = Hello.instance_methods.ai(:plain => true, :index => false).split("\n").grep(/m\d/)
|
217
|
+
if RUBY_VERSION < '1.9.2'
|
218
|
+
out.first.should =~ /^\s+m3\(arg1, arg2\)\s+Hello\s\(unbound\)$/
|
219
|
+
else
|
220
|
+
out.first.should =~ /^\s+m3\(a, b\)\s+Hello\s\(unbound\)$/
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
describe "class.public_instance_methods" do
|
226
|
+
it "index: should handle class.public_instance_methods" do
|
227
|
+
class Hello
|
228
|
+
def m1; end
|
229
|
+
def m2; end
|
230
|
+
end
|
231
|
+
out = Hello.public_instance_methods.ai(:plain => true).split("\n").grep(/m\d/)
|
232
|
+
out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(\)\s+Hello\s\(unbound\)$/
|
233
|
+
out.last.should =~ /^\s+\[\s*\d+\]\s+m2\(\)\s+Hello\s\(unbound\)$/
|
234
|
+
end
|
235
|
+
|
236
|
+
it "no index: should handle class.public_instance_methods" do
|
237
|
+
class Hello
|
238
|
+
def m3(a,b); end
|
239
|
+
end
|
240
|
+
out = Hello.public_instance_methods.ai(:plain => true, :index => false).split("\n").grep(/m\d/)
|
241
|
+
if RUBY_VERSION < '1.9.2'
|
242
|
+
out.first.should =~ /^\s+m3\(arg1, arg2\)\s+Hello\s\(unbound\)$/
|
243
|
+
else
|
244
|
+
out.first.should =~ /^\s+m3\(a, b\)\s+Hello\s\(unbound\)$/
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
describe "class.protected_instance_methods" do
|
250
|
+
it "index: should handle class.protected_instance_methods" do
|
251
|
+
class Hello
|
252
|
+
protected
|
253
|
+
def m1; end
|
254
|
+
def m2; end
|
255
|
+
end
|
256
|
+
out = Hello.protected_instance_methods.ai(:plain => true).split("\n").grep(/m\d/)
|
257
|
+
out.first.should =~ /^\s+\[\d+\]\s+m1\(\)\s+Hello\s\(unbound\)$/
|
258
|
+
out.last.should =~ /^\s+\[\d+\]\s+m2\(\)\s+Hello\s\(unbound\)$/
|
259
|
+
end
|
260
|
+
|
261
|
+
it "no index: should handle class.protected_instance_methods" do
|
262
|
+
class Hello
|
263
|
+
protected
|
264
|
+
def m3(a,b); end
|
265
|
+
end
|
266
|
+
out = Hello.protected_instance_methods.ai(:plain => true, :index => false).split("\n").grep(/m\d/)
|
267
|
+
if RUBY_VERSION < '1.9.2'
|
268
|
+
out.first.should =~ /^\s+m3\(arg1, arg2\)\s+Hello\s\(unbound\)$/
|
269
|
+
else
|
270
|
+
out.first.should =~ /^\s+m3\(a, b\)\s+Hello\s\(unbound\)$/
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
describe "class.private_instance_methods" do
|
276
|
+
it "index: should handle class.private_instance_methods" do
|
277
|
+
class Hello
|
278
|
+
private
|
279
|
+
def m1; end
|
280
|
+
def m2; end
|
281
|
+
end
|
282
|
+
out = Hello.private_instance_methods.ai(:plain => true).split("\n").grep(/m\d/)
|
283
|
+
out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(\)\s+Hello\s\(unbound\)$/
|
284
|
+
out.last.should =~ /^\s+\[\s*\d+\]\s+m2\(\)\s+Hello\s\(unbound\)$/
|
285
|
+
end
|
286
|
+
|
287
|
+
it "no index: should handle class.private_instance_methods" do
|
288
|
+
class Hello
|
289
|
+
private
|
290
|
+
def m3(a,b); end
|
291
|
+
end
|
292
|
+
out = Hello.private_instance_methods.ai(:plain => true, :index => false).split("\n").grep(/m\d/)
|
293
|
+
if RUBY_VERSION < '1.9.2'
|
294
|
+
out.first.should =~ /^\s+m3\(arg1, arg2\)\s+Hello\s\(unbound\)$/
|
295
|
+
else
|
296
|
+
out.first.should =~ /^\s+m3\(a, b\)\s+Hello\s\(unbound\)$/
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
if RUBY_VERSION >= '1.9.2'
|
303
|
+
describe "Ruby 1.9.2+ Method#parameters" do
|
304
|
+
after do
|
305
|
+
Object.instance_eval{ remove_const :Hello } if defined?(Hello)
|
306
|
+
end
|
307
|
+
|
308
|
+
it "()" do
|
309
|
+
class Hello
|
310
|
+
def m1; end
|
311
|
+
end
|
312
|
+
out = Hello.new.methods.ai(:plain => true).split("\n").grep(/m1/)
|
313
|
+
out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(\)\s+Hello$/
|
314
|
+
end
|
315
|
+
|
316
|
+
it ":req" do
|
317
|
+
class Hello
|
318
|
+
def m1(a, b, c); end
|
319
|
+
end
|
320
|
+
out = Hello.new.methods.ai(:plain => true).split("\n").grep(/m1/)
|
321
|
+
out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(a, b, c\)\s+Hello$/
|
322
|
+
end
|
323
|
+
|
324
|
+
it ":opt" do
|
325
|
+
class Hello
|
326
|
+
def m1(a, b = 1, c = 2); end # m1(a, *b, *c)
|
327
|
+
end
|
328
|
+
out = Hello.new.methods.ai(:plain => true).split("\n").grep(/m1/)
|
329
|
+
out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(a, \*b, \*c\)\s+Hello$/
|
330
|
+
end
|
331
|
+
|
332
|
+
it ":rest" do
|
333
|
+
class Hello
|
334
|
+
def m1(*a); end # m1(*a)
|
335
|
+
end
|
336
|
+
out = Hello.new.methods.ai(:plain => true).split("\n").grep(/m1/)
|
337
|
+
out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(\*a\)\s+Hello$/
|
338
|
+
end
|
339
|
+
|
340
|
+
it ":block" do
|
341
|
+
class Hello
|
342
|
+
def m1(a, b = nil, &blk); end # m1(a, *b, &blk)
|
343
|
+
end
|
344
|
+
out = Hello.new.methods.ai(:plain => true).split("\n").grep(/m1/)
|
345
|
+
out.first.should =~ /^\s+\[\s*\d+\]\s+m1\(a, \*b, &blk\)\s+Hello$/
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
describe "Methods arrays" do
|
351
|
+
after do
|
352
|
+
Object.instance_eval{ remove_const :Hello } if defined?(Hello)
|
353
|
+
Object.instance_eval{ remove_const :World } if defined?(World)
|
354
|
+
end
|
355
|
+
|
356
|
+
it "obj1.methods - obj2.methods should be awesome printed" do
|
357
|
+
class Hello
|
358
|
+
def self.m1; end
|
359
|
+
end
|
360
|
+
out = (Hello.methods - Class.methods).ai(:plain => true)
|
361
|
+
out.should == "[\n [0] m1() Hello\n]"
|
362
|
+
end
|
363
|
+
|
364
|
+
it "obj1.methods & obj2.methods should be awesome printed" do
|
365
|
+
class Hello
|
366
|
+
def self.m1; end
|
367
|
+
def self.m2; end
|
368
|
+
end
|
369
|
+
class World
|
370
|
+
def self.m1; end
|
371
|
+
end
|
372
|
+
out = (Hello.methods & World.methods - Class.methods).ai(:plain => true)
|
373
|
+
out.should == "[\n [0] m1() Hello\n]"
|
374
|
+
end
|
375
|
+
|
376
|
+
it "obj1.methods.grep(pattern) should be awesome printed" do
|
377
|
+
class Hello
|
378
|
+
def self.m1; end
|
379
|
+
def self.m2; end
|
380
|
+
def self.m3; end
|
381
|
+
end
|
382
|
+
out = Hello.methods.grep(/^m1$/).ai(:plain => true)
|
383
|
+
out.should == "[\n [0] m1() Hello\n]"
|
384
|
+
out = Hello.methods.grep(/^m\d$/).ai(:plain => true)
|
385
|
+
out.should == "[\n [0] m1() Hello\n [1] m2() Hello\n [2] m3() Hello\n]"
|
386
|
+
end
|
387
|
+
|
388
|
+
it "obj1.methods.grep(pattern, &block) should pass the matching string within the block" do
|
389
|
+
class Hello
|
390
|
+
def self.m_one; end
|
391
|
+
def self.m_two; end
|
392
|
+
end
|
393
|
+
|
394
|
+
out = Hello.methods.grep(/^m_(.+)$/) { $1.to_sym }
|
395
|
+
out.should == [:one, :two]
|
396
|
+
end
|
397
|
+
|
398
|
+
it "obj1.methods.grep(pattern, &block) should be awesome printed" do
|
399
|
+
class Hello
|
400
|
+
def self.m0; end
|
401
|
+
def self.none; end
|
402
|
+
def self.m1; end
|
403
|
+
def self.one; end
|
404
|
+
end
|
405
|
+
|
406
|
+
out = Hello.methods.grep(/^m(\d)$/) { %w(none one)[$1.to_i] }.ai(:plain => true)
|
407
|
+
out.should == "[\n [0] none() Hello\n [1] one() Hello\n]"
|
408
|
+
end
|
409
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,11 +1,25 @@
|
|
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
|
+
#
|
7
|
+
# Running specs with Ruby 1.8.7 and RSpec 1.3+:
|
8
|
+
# $ rake spec # Entire spec suite.
|
9
|
+
# $ ruby -rubygems spec/logger_spec.rb # Individual spec file.
|
10
|
+
#
|
11
|
+
# Running specs with Ruby 1.9.2 and RSpec 2.0+:
|
12
|
+
# $ rake spec # Entire spec suite.
|
13
|
+
# $ rspec spec/logger_spec.rb # Individual spec file.
|
14
|
+
#
|
1
15
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
16
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
17
|
require 'ap'
|
4
|
-
require 'spec'
|
5
|
-
require 'spec/autorun'
|
6
|
-
require 'rubygems'
|
7
18
|
|
8
|
-
|
19
|
+
if RUBY_VERSION.to_f < 1.9
|
20
|
+
require 'spec'
|
21
|
+
require 'spec/autorun'
|
22
|
+
require 'rubygems'
|
9
23
|
end
|
10
24
|
|
11
25
|
def stub_dotfile!
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 3
|
8
|
+
- 0
|
9
|
+
version: 0.3.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Michael Dvorkin
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-11-09 00:00:00 -08:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -26,9 +26,9 @@ dependencies:
|
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
segments:
|
28
28
|
- 1
|
29
|
-
-
|
30
|
-
-
|
31
|
-
version: 1.
|
29
|
+
- 3
|
30
|
+
- 0
|
31
|
+
version: 1.3.0
|
32
32
|
type: :development
|
33
33
|
version_requirements: *id001
|
34
34
|
description: "Great Ruby dubugging companion: pretty print Ruby objects to visualize their structure. Supports Rails ActiveRecord objects via included mixin."
|
@@ -49,18 +49,22 @@ files:
|
|
49
49
|
- init.rb
|
50
50
|
- lib/ap.rb
|
51
51
|
- lib/ap/awesome_print.rb
|
52
|
+
- lib/ap/core_ext/array.rb
|
53
|
+
- lib/ap/core_ext/class.rb
|
52
54
|
- lib/ap/core_ext/kernel.rb
|
53
55
|
- lib/ap/core_ext/logger.rb
|
56
|
+
- lib/ap/core_ext/object.rb
|
54
57
|
- lib/ap/core_ext/string.rb
|
55
58
|
- lib/ap/mixin/action_view.rb
|
56
59
|
- lib/ap/mixin/active_record.rb
|
57
60
|
- lib/ap/mixin/active_support.rb
|
61
|
+
- lib/awesome_print.rb
|
58
62
|
- rails/init.rb
|
59
63
|
- spec/action_view_spec.rb
|
60
64
|
- spec/active_record_spec.rb
|
61
65
|
- spec/awesome_print_spec.rb
|
62
66
|
- spec/logger_spec.rb
|
63
|
-
- spec/
|
67
|
+
- spec/methods_spec.rb
|
64
68
|
- spec/spec_helper.rb
|
65
69
|
- spec/string_spec.rb
|
66
70
|
has_rdoc: true
|
@@ -98,5 +102,6 @@ test_files:
|
|
98
102
|
- spec/active_record_spec.rb
|
99
103
|
- spec/awesome_print_spec.rb
|
100
104
|
- spec/logger_spec.rb
|
105
|
+
- spec/methods_spec.rb
|
101
106
|
- spec/spec_helper.rb
|
102
107
|
- spec/string_spec.rb
|
data/spec/spec.opts
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
--color
|