awesome_print 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|