awesome_dump 0.0.1
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 +3 -0
- data/LICENSE +23 -0
- data/README.md +106 -0
- data/Rakefile +48 -0
- data/VERSION +1 -0
- data/init.rb +1 -0
- data/lib/ad.rb +14 -0
- data/lib/ad/awesome_dump.rb +225 -0
- data/lib/ad/core_ext/kernel.rb +13 -0
- data/lib/ad/core_ext/logger.rb +17 -0
- data/lib/ad/core_ext/string.rb +27 -0
- data/lib/ad/mixin/active_record.rb +32 -0
- data/lib/ad/mixin/active_support.rb +23 -0
- data/rails/init.rb +1 -0
- data/spec/active_record_spec.rb +117 -0
- data/spec/awesome_dump_spec.rb +234 -0
- data/spec/logger_spec.rb +43 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/string_spec.rb +20 -0
- metadata +106 -0
data/CHANGELOG
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Copyright (c) 2010 Slippy Douglas
|
|
2
|
+
|
|
3
|
+
Based on awesome_print, Copyright (c) 2010 Michael Dvorkin
|
|
4
|
+
%w(mike dvorkin.net) * "@" || %w(mike fatfreecrm.com) * "@"
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
7
|
+
a copy of this software and associated documentation files (the
|
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
12
|
+
the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be
|
|
15
|
+
included in all copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
21
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
22
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
## Awesome Dump ##
|
|
2
|
+
Awesome Dump is Ruby library that dumps Ruby objects as nested hashes/arrays, exposing their internal structure in a form safe for conversion to JSON, YAML, or other data formats.
|
|
3
|
+
|
|
4
|
+
Notes:
|
|
5
|
+
|
|
6
|
+
* Makes sure recursive object graphs are ellipse'd and all relevant data is outputted cleanly (i.e. advantages over just using a plain to_json).
|
|
7
|
+
* Awesome Dump'ed data looks awesome when converted to_json, then viewed with a JSON viewer (e.g. JSONView (https://addons.mozilla.org/en-US/firefox/addon/10869/), FirePHP/FireConsole (http://www.firephp.org/), or json2html (http://json.bloople.net/)).
|
|
8
|
+
* This library is very much not-done. It's inconsistent at times and subject to lots of improvement.
|
|
9
|
+
|
|
10
|
+
### Installation ###
|
|
11
|
+
# Installing as Rails plugin
|
|
12
|
+
$ ruby script/plugin install git://github.com/slippyd/awesome_dump.git
|
|
13
|
+
|
|
14
|
+
# Installing as a Ruby library
|
|
15
|
+
$ git clone git://github.com/slippyd/awesome_dump.git lib/awesome_dump
|
|
16
|
+
|
|
17
|
+
# Installing as a Ruby library, with Git submodules
|
|
18
|
+
$ git submodule add git://github.com/slippyd/awesome_dump.git lib/awesome_dump
|
|
19
|
+
$ git submodule init
|
|
20
|
+
$ git submodule update
|
|
21
|
+
|
|
22
|
+
# Cloning the repository
|
|
23
|
+
$ git clone git://github.com/slippyd/awesome_dump.git
|
|
24
|
+
|
|
25
|
+
### Usage ###
|
|
26
|
+
|
|
27
|
+
require 'ad'
|
|
28
|
+
some_object.ad
|
|
29
|
+
|
|
30
|
+
require 'ad', 'json'
|
|
31
|
+
some_object.ad(:escape => :safe).to_json
|
|
32
|
+
|
|
33
|
+
require 'ad', 'yaml'
|
|
34
|
+
some_object.ad(:escape => :quote).to_yaml
|
|
35
|
+
|
|
36
|
+
Supported options:
|
|
37
|
+
|
|
38
|
+
* ":escape => :safe": Quotes constructs that probably won't translate well into languages other than Ruby (e.g. symbols, classes). Can result in ambigious or lossy results if naming conflicts occur.
|
|
39
|
+
* ":escape => :quote": Quotes every piece of data that's dumped (i.e. numbers become strings and Strings become strings that start and end with a quote). Theoretically, this conversion should be reversible back into the original data.
|
|
40
|
+
|
|
41
|
+
### Examples ###
|
|
42
|
+
|
|
43
|
+
Ruby:
|
|
44
|
+
|
|
45
|
+
require 'rubygems'
|
|
46
|
+
require 'json'
|
|
47
|
+
require 'awesome_dump/init'
|
|
48
|
+
|
|
49
|
+
class Cow
|
|
50
|
+
def initialize
|
|
51
|
+
@moo = true
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
data = [false, 42, %w(forty two), {:how => 'now', 'brown' => Cow.new}]
|
|
56
|
+
puts "inspect:\n\t" + data.inspect
|
|
57
|
+
puts "ad.inspect:\n\t" + data.ad.inspect
|
|
58
|
+
puts "to_json:\n\t" + data.to_json
|
|
59
|
+
puts "ad(:escape => :safe).to_json:\n\t" + data.ad(:escape => :safe).to_json
|
|
60
|
+
|
|
61
|
+
Output:
|
|
62
|
+
|
|
63
|
+
inspect:
|
|
64
|
+
[false, 42, ["forty", "two"], {:how=>"now", "brown"=>#<Cow:0x101069210 @moo=true>}]
|
|
65
|
+
ad.inspect:
|
|
66
|
+
[false, 42, ["forty", "two"], {:how=>"now", "brown"=>{:@moo=>true, :class=>Cow, :object_id=>2156087560}}]
|
|
67
|
+
to_json:
|
|
68
|
+
[false,42,["forty","two"],{"how":"now","brown":"#<Cow:0x101069210>"}]
|
|
69
|
+
ad(:escape => :safe).to_json:
|
|
70
|
+
[false,42,["forty","two"],{":how":"now","brown":{"class":"Cow","@moo":true,"object_id":2156087560}}]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
### Setting Custom Defaults ###
|
|
74
|
+
You can set your own default options by creating ``.adrc`` file in your home
|
|
75
|
+
directory. Within that file assign your defaults to ``AwesomeDump.defaults``.
|
|
76
|
+
For example:
|
|
77
|
+
|
|
78
|
+
# ~/.adrc file.
|
|
79
|
+
AwesomeDump.defaults = {
|
|
80
|
+
:escape => :quote
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
### Note on Patches/Pull Requests ###
|
|
84
|
+
* Fork the project on Github.
|
|
85
|
+
* Make your feature addition or bug fix.
|
|
86
|
+
* Add specs for it, making sure $ rake spec is all green.
|
|
87
|
+
* Commit, do not mess with rakefile, version, or history.
|
|
88
|
+
* Send me a pull request.
|
|
89
|
+
|
|
90
|
+
### Contributors ###
|
|
91
|
+
|
|
92
|
+
awesome_print:
|
|
93
|
+
|
|
94
|
+
* Michael Dvorkin -- http://github.com/michaeldv
|
|
95
|
+
* Daniel Bretoi -- http://github.com/danielb2
|
|
96
|
+
* eregon -- http://github.com/eregon
|
|
97
|
+
* Tobias Crawley -- http://github.com/tobias
|
|
98
|
+
|
|
99
|
+
### License ###
|
|
100
|
+
Copyright (c) 2010 Slippy Douglas
|
|
101
|
+
'awesome_dump' + 64.chr + 'slippyd.com'
|
|
102
|
+
|
|
103
|
+
Based on awesome_print, Copyright (c) 2010 Michael Dvorkin
|
|
104
|
+
%w(mike dvorkin.net) * "@" || %w(mike fatfreecrm.com) * "@"
|
|
105
|
+
|
|
106
|
+
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_dump"
|
|
8
|
+
gem.rubyforge_project = "awesome_dump"
|
|
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/slippyd/awesome_dump"
|
|
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 = "ad #{version}"
|
|
46
|
+
rdoc.rdoc_files.include('README*')
|
|
47
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
48
|
+
end
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.0.1
|
data/init.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), "lib", "ad")
|
data/lib/ad.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Copyright (c) 2010 Slippy Douglas & Michael Dvorkin
|
|
2
|
+
#
|
|
3
|
+
# Awesome Dump 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__) + "/ad/core_ext/string"
|
|
7
|
+
require File.dirname(__FILE__) + "/ad/core_ext/kernel"
|
|
8
|
+
require File.dirname(__FILE__) + "/ad/awesome_dump"
|
|
9
|
+
|
|
10
|
+
require File.dirname(__FILE__) + "/ad/core_ext/logger" if defined?(::Logger) or defined?(::ActiveSupport::BufferedLogger)
|
|
11
|
+
|
|
12
|
+
#require File.dirname(__FILE__) + "/ad/mixin/active_record" if defined?(::ActiveRecord)
|
|
13
|
+
#require File.dirname(__FILE__) + "/ad/mixin/active_support" if defined?(::ActiveSupport)
|
|
14
|
+
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# Copyright (c) 2010 Slippy Douglas & Michael Dvorkin
|
|
2
|
+
#
|
|
3
|
+
# Awesome Dump 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 "shellwords"
|
|
7
|
+
|
|
8
|
+
class AwesomeDump
|
|
9
|
+
AD = :__awesome_dump__
|
|
10
|
+
|
|
11
|
+
def initialize(options = {})
|
|
12
|
+
@options = {
|
|
13
|
+
:multiline => true,
|
|
14
|
+
:plain => false,
|
|
15
|
+
:indent => 4,
|
|
16
|
+
:color => {
|
|
17
|
+
:array => :white,
|
|
18
|
+
:bigdecimal => :blue,
|
|
19
|
+
:class => :yellow,
|
|
20
|
+
:date => :greenish,
|
|
21
|
+
:falseclass => :red,
|
|
22
|
+
:fixnum => :blue,
|
|
23
|
+
:float => :blue,
|
|
24
|
+
:hash => :pale,
|
|
25
|
+
:struct => :pale,
|
|
26
|
+
:nilclass => :red,
|
|
27
|
+
:string => :yellowish,
|
|
28
|
+
:symbol => :cyanish,
|
|
29
|
+
:time => :greenish,
|
|
30
|
+
:trueclass => :green
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# Merge custom defaults and let explicit options parameter override them.
|
|
35
|
+
merge_custom_defaults!
|
|
36
|
+
merge_options!(options)
|
|
37
|
+
|
|
38
|
+
@indentation = @options[:indent].abs
|
|
39
|
+
Thread.current[AD] ||= []
|
|
40
|
+
|
|
41
|
+
@formatter = Formatter.new(self.method(:awesome), @options)
|
|
42
|
+
|
|
43
|
+
extend Util
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
## Dispatcher that detects data nesting and invokes object-aware formatter.
|
|
49
|
+
def awesome(object)
|
|
50
|
+
if Thread.current[AD].include?(object.object_id)
|
|
51
|
+
nested(object)
|
|
52
|
+
else
|
|
53
|
+
begin
|
|
54
|
+
Thread.current[AD] << object.object_id
|
|
55
|
+
return eval(%<@formatter.#{declassify(object)}(object)>)
|
|
56
|
+
ensure
|
|
57
|
+
Thread.current[AD].pop
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
class Formatter
|
|
63
|
+
def initialize(awesome_method, options = {})
|
|
64
|
+
@awesome = awesome_method
|
|
65
|
+
@options = options
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
## Format an array.
|
|
69
|
+
def array(a)
|
|
70
|
+
return [] if a == []
|
|
71
|
+
|
|
72
|
+
return a.inject([]) { |arr, item| arr << @awesome.call(item) }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
## Format a hash. If @options[:indent] if negative left align hash keys.
|
|
76
|
+
def hash(h)
|
|
77
|
+
return {} if h == {}
|
|
78
|
+
return h.keys.inject({}) do |hash, key|
|
|
79
|
+
hash.store @awesome.call(key), @awesome.call(h[key])
|
|
80
|
+
hash
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def fixnum(f)
|
|
85
|
+
return f.to_s if @options[:escape] == :quote
|
|
86
|
+
return f
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def nilclass(n)
|
|
90
|
+
return 'nil' if @options[:escape] == :quote
|
|
91
|
+
return nil
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def trueclass(n)
|
|
95
|
+
return 'true' if @options[:escape] == :quote
|
|
96
|
+
return true
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def falseclass(n)
|
|
100
|
+
return 'false' if @options[:escape] == :quote
|
|
101
|
+
return false
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def symbol(s)
|
|
105
|
+
return s.to_s.include?(':') ? %{:"#{s}"} : %{:#{s}} if [:quote, :safe].include?(@options[:escape])
|
|
106
|
+
return s
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def string(s)
|
|
110
|
+
return %{"#{s}"} if @options[:escape] == :quote
|
|
111
|
+
return s
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
## Format a Struct. If @options[:indent] if negative left align hash keys.
|
|
115
|
+
def struct(s)
|
|
116
|
+
h = {}
|
|
117
|
+
s.each_pair do |m, v|
|
|
118
|
+
m_k = [:quote, :safe].include?(@options[:escape]) ? m.to_s : m.to_sym
|
|
119
|
+
h[m_k] = @awesome.call(v)
|
|
120
|
+
end
|
|
121
|
+
return object(s, h)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
## Format Class object.
|
|
125
|
+
def class(c)
|
|
126
|
+
if [:quote, :safe].include?(@options[:escape])
|
|
127
|
+
sc = c.superclass
|
|
128
|
+
return %{#{c} < #{sc}} if sc && sc != Object
|
|
129
|
+
return c.to_s
|
|
130
|
+
end
|
|
131
|
+
return c
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
## Format File object.
|
|
135
|
+
def file(f)
|
|
136
|
+
ls = File.directory?(f) ? `ls -adlF #{f.path.shellescape}` : `ls -alF #{f.path.shellescape}`
|
|
137
|
+
return object(f) #, :with => ls.empty? ? nil : "\n#{ls.chop}")
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
## Format Dir object.
|
|
141
|
+
def dir(d)
|
|
142
|
+
ls = `ls -alF #{d.path.shellescape}`
|
|
143
|
+
return object(d) #, :with => ls.empty? ? nil : "\n#{ls.chop}")
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
## Format BigDecimal and Rational objects by convering them to Float.
|
|
147
|
+
def bigdecimal(n)
|
|
148
|
+
return object(n.to_f) #, :as => :bigdecimal
|
|
149
|
+
end
|
|
150
|
+
alias :rational :bigdecimal
|
|
151
|
+
|
|
152
|
+
## Format an arbitrary object.
|
|
153
|
+
def object(o, with=nil)
|
|
154
|
+
o_hash = case @options[:escape]
|
|
155
|
+
when :quote then {'class' => o.class.to_s, 'object_id' => o.object_id.to_s}
|
|
156
|
+
when :safe then {'class' => o.class.to_s, 'object_id' => o.object_id}
|
|
157
|
+
else {:class => o.class, :object_id => o.object_id}
|
|
158
|
+
end
|
|
159
|
+
o.instance_variables.sort.each do |iv|
|
|
160
|
+
iv_k = [:quote, :safe].include?(@options[:escape]) ? iv.to_s : iv.to_sym
|
|
161
|
+
o_hash[iv_k] = @awesome.call(o.instance_variable_get(iv))
|
|
162
|
+
end
|
|
163
|
+
o_hash = with.merge(o_hash) if with
|
|
164
|
+
return o_hash
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
## Catch-all method to format an arbitrary object.
|
|
168
|
+
def method_missing(method_id, object)
|
|
169
|
+
return object(object)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
module Util
|
|
175
|
+
## Format nested data, for example:
|
|
176
|
+
## arr = [1, 2]; arr << arr
|
|
177
|
+
## => [1,2, [...]]
|
|
178
|
+
## hsh = { :a => 1 }; hsh[:b] = hsh
|
|
179
|
+
## => { :a => 1, :b => {...} }
|
|
180
|
+
def nested(object)
|
|
181
|
+
case declassify(object)
|
|
182
|
+
when :array then ['...']
|
|
183
|
+
when :hash then {'...' => '...'}
|
|
184
|
+
when :struct then {'...' => '...'}
|
|
185
|
+
else "...#{object.class}..."
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
## Turn class name into symbol, ex: Hello::World => :hello_world.
|
|
190
|
+
def declassify(object)
|
|
191
|
+
if object.is_a?(Struct)
|
|
192
|
+
:struct
|
|
193
|
+
else
|
|
194
|
+
object.class.to_s.gsub(/:+/, "_").downcase.to_sym
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
## Update @options by first merging the :color hash and then the remaining keys.
|
|
200
|
+
def merge_options!(options = {})
|
|
201
|
+
@options[:color].merge!(options.delete(:color) || {})
|
|
202
|
+
@options.merge!(options)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
## Load ~/.adrc file with custom defaults that override default options.
|
|
206
|
+
def merge_custom_defaults!
|
|
207
|
+
dotfile = File.join(ENV["HOME"], ".adrc")
|
|
208
|
+
if File.readable?(dotfile)
|
|
209
|
+
load dotfile
|
|
210
|
+
merge_options!(self.class.defaults)
|
|
211
|
+
end
|
|
212
|
+
rescue => e
|
|
213
|
+
$stderr.puts "Could not load #{dotfile}: #{e}"
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
## Class accessors for custom defaults.
|
|
217
|
+
def self.defaults
|
|
218
|
+
@@defaults ||= {}
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def self.defaults=(args = {})
|
|
222
|
+
@@defaults = args
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Copyright (c) 2010 Slippy Douglas & Michael Dvorkin
|
|
2
|
+
#
|
|
3
|
+
# Awesome Dump 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 ad(options = {})
|
|
9
|
+
ad = AwesomeDump.new(options)
|
|
10
|
+
ad.send(:awesome, self)
|
|
11
|
+
end
|
|
12
|
+
alias :awesome_dump :ad
|
|
13
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Copyright (c) 2010 Slippy Douglas & Michael Dvorkin
|
|
2
|
+
#
|
|
3
|
+
# Awesome Dump 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 AwesomeDumpLogger
|
|
7
|
+
|
|
8
|
+
# Add ad method to logger
|
|
9
|
+
def ad(object, level = nil)
|
|
10
|
+
level ||= AwesomeDump.defaults[:log_level] || :debug
|
|
11
|
+
send level, object.ad
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Logger.send(:include, AwesomeDumpLogger) if defined?(Logger)
|
|
17
|
+
ActiveSupport::BufferedLogger.send(:include, AwesomeDumpLogger) if defined?(::ActiveSupport::BufferedLogger)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Copyright (c) 2010 Slippy Douglas & Michael Dvorkin
|
|
2
|
+
#
|
|
3
|
+
# Awesome Dump 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
|
|
7
|
+
|
|
8
|
+
# ANSI color codes:
|
|
9
|
+
# \033 => escape
|
|
10
|
+
# 30 => color base
|
|
11
|
+
# 1 => bright
|
|
12
|
+
# 0 => normal
|
|
13
|
+
|
|
14
|
+
[ :gray, :red, :green, :yellow, :blue, :purple, :cyan, :white ].each_with_index do |color, i|
|
|
15
|
+
if STDOUT.tty? && ENV['TERM'] && ENV['TERM'] != 'dumb'
|
|
16
|
+
define_method color do "\033[1;#{30+i}m#{self}\033[0m" end
|
|
17
|
+
define_method :"#{color}ish" do "\033[0;#{30+i}m#{self}\033[0m" end
|
|
18
|
+
else
|
|
19
|
+
define_method color do self end
|
|
20
|
+
alias_method :"#{color}ish", color
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
alias :black :grayish
|
|
25
|
+
alias :pale :whiteish
|
|
26
|
+
|
|
27
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Copyright (c) 2010 Slippy Douglas & Michael Dvorkin
|
|
2
|
+
#
|
|
3
|
+
# Awesome Dump 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 AwesomeDumpActiveRecord
|
|
7
|
+
|
|
8
|
+
# Format ActiveRecord instance object.
|
|
9
|
+
def awesome_active_record_instance(object)
|
|
10
|
+
data = object.class.column_names.inject(ActiveSupport::OrderedHash.new) do |hash, name|
|
|
11
|
+
hash[name.to_sym] = object.send(name) if object.has_attribute?(name) || object.new_record?
|
|
12
|
+
hash
|
|
13
|
+
end
|
|
14
|
+
"#{object} " + awesome_hash(data)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Format ActiveRecord class object.
|
|
18
|
+
def awesome_active_record_class(object)
|
|
19
|
+
if object.respond_to?(:columns)
|
|
20
|
+
data = object.columns.inject(ActiveSupport::OrderedHash.new) do |hash, c|
|
|
21
|
+
hash[c.name.to_sym] = c.type
|
|
22
|
+
hash
|
|
23
|
+
end
|
|
24
|
+
"class #{object} < #{object.superclass} " << awesome_hash(data)
|
|
25
|
+
else
|
|
26
|
+
object.inspect
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
AwesomeDump.send(:include, AwesomeDumpActiveRecord)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Copyright (c) 2010 Slippy Douglas & Michael Dvorkin
|
|
2
|
+
#
|
|
3
|
+
# Awesome Dump 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 AwesomeDumpActiveSupport
|
|
7
|
+
|
|
8
|
+
# Format ActiveSupport::TimeWithZone as standard Time.
|
|
9
|
+
def awesome_active_support_time(object)
|
|
10
|
+
awesome_self(object, :as => :time)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Format HashWithIndifferentAccess as standard Hash.
|
|
14
|
+
#
|
|
15
|
+
# NOTE: can't use awesome_self(object, :as => :hash) since awesome_self uses
|
|
16
|
+
# object.inspect internally, i.e. it would convert hash to string.
|
|
17
|
+
def awesome_hash_with_indifferent_access(object)
|
|
18
|
+
awesome_hash(object)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
AwesomeDump.send(:include, AwesomeDumpActiveSupport)
|
data/rails/init.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), "..", "init")
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
|
+
#
|
|
3
|
+
#require 'active_record'
|
|
4
|
+
#require 'ad/mixin/active_record'
|
|
5
|
+
#
|
|
6
|
+
#
|
|
7
|
+
#if defined?(::ActiveRecord)
|
|
8
|
+
#
|
|
9
|
+
# # Create tableless ActiveRecord model.
|
|
10
|
+
# class User < ActiveRecord::Base
|
|
11
|
+
# def self.columns()
|
|
12
|
+
# @columns ||= []
|
|
13
|
+
# end
|
|
14
|
+
#
|
|
15
|
+
# def self.column(name, sql_type = nil, default = nil, null = true)
|
|
16
|
+
# columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
|
|
17
|
+
# end
|
|
18
|
+
#
|
|
19
|
+
# column :id, :integer
|
|
20
|
+
# column :name, :string
|
|
21
|
+
# column :rank, :integer
|
|
22
|
+
# column :admin, :boolean
|
|
23
|
+
# column :created_at, :datetime
|
|
24
|
+
#
|
|
25
|
+
# def self.table_exists?
|
|
26
|
+
# true
|
|
27
|
+
# end
|
|
28
|
+
# end
|
|
29
|
+
#
|
|
30
|
+
# class SubUser < User
|
|
31
|
+
# def self.columns
|
|
32
|
+
# User.columns
|
|
33
|
+
# end
|
|
34
|
+
# end
|
|
35
|
+
#
|
|
36
|
+
# describe "AwesomeDump/ActiveRecord" do
|
|
37
|
+
# before(:each) do
|
|
38
|
+
# stub_dotfile!
|
|
39
|
+
# end
|
|
40
|
+
#
|
|
41
|
+
# #------------------------------------------------------------------------------
|
|
42
|
+
# describe "ActiveRecord instance" do
|
|
43
|
+
# before(:each) do
|
|
44
|
+
# ActiveRecord::Base.default_timezone = :utc
|
|
45
|
+
# @diana = User.new(:name => "Diana", :rank => 1, :admin => false, :created_at => "1992-10-10 12:30:00")
|
|
46
|
+
# @laura = User.new(:name => "Laura", :rank => 2, :admin => true, :created_at => "2003-05-26 14:15:00")
|
|
47
|
+
# @ad = AwesomeDump.new(:plain => true)
|
|
48
|
+
# end
|
|
49
|
+
#
|
|
50
|
+
# it "display single record" do
|
|
51
|
+
# out = @ad.send(:awesome, @diana)
|
|
52
|
+
# out.gsub(/0x([a-f\d]+)/, "0x01234567").should == <<-EOS.strip
|
|
53
|
+
##<User:0x01234567> {
|
|
54
|
+
# :id => nil,
|
|
55
|
+
# :name => "Diana",
|
|
56
|
+
# :rank => 1,
|
|
57
|
+
# :admin => false,
|
|
58
|
+
# :created_at => Sat Oct 10 12:30:00 UTC 1992
|
|
59
|
+
#}
|
|
60
|
+
#EOS
|
|
61
|
+
# end
|
|
62
|
+
#
|
|
63
|
+
# it "display multiple records" do
|
|
64
|
+
# out = @ad.send(:awesome, [ @diana, @laura ])
|
|
65
|
+
# out.gsub(/0x([a-f\d]+)/, "0x01234567").should == <<-EOS.strip
|
|
66
|
+
#[
|
|
67
|
+
# [0] #<User:0x01234567> {
|
|
68
|
+
# :id => nil,
|
|
69
|
+
# :name => "Diana",
|
|
70
|
+
# :rank => 1,
|
|
71
|
+
# :admin => false,
|
|
72
|
+
# :created_at => Sat Oct 10 12:30:00 UTC 1992
|
|
73
|
+
# },
|
|
74
|
+
# [1] #<User:0x01234567> {
|
|
75
|
+
# :id => nil,
|
|
76
|
+
# :name => "Laura",
|
|
77
|
+
# :rank => 2,
|
|
78
|
+
# :admin => true,
|
|
79
|
+
# :created_at => Mon May 26 14:15:00 UTC 2003
|
|
80
|
+
# }
|
|
81
|
+
#]
|
|
82
|
+
#EOS
|
|
83
|
+
# end
|
|
84
|
+
# end
|
|
85
|
+
#
|
|
86
|
+
# #------------------------------------------------------------------------------
|
|
87
|
+
# describe "ActiveRecord class" do
|
|
88
|
+
# it "should print the class" do
|
|
89
|
+
# @ad = AwesomeDump.new(:plain => true)
|
|
90
|
+
# @ad.send(:awesome, User).should == <<-EOS.strip
|
|
91
|
+
#class User < ActiveRecord::Base {
|
|
92
|
+
# :id => :integer,
|
|
93
|
+
# :name => :string,
|
|
94
|
+
# :rank => :integer,
|
|
95
|
+
# :admin => :boolean,
|
|
96
|
+
# :created_at => :datetime
|
|
97
|
+
#}
|
|
98
|
+
# EOS
|
|
99
|
+
#
|
|
100
|
+
#end
|
|
101
|
+
#
|
|
102
|
+
#it "should print the class for non-direct subclasses of AR::Base" do
|
|
103
|
+
# @ad = AwesomeDump.new(:plain => true)
|
|
104
|
+
# @ad.send(:awesome, SubUser).should == <<-EOS.strip
|
|
105
|
+
#class SubUser < User {
|
|
106
|
+
# :id => :integer,
|
|
107
|
+
# :name => :string,
|
|
108
|
+
# :rank => :integer,
|
|
109
|
+
# :admin => :boolean,
|
|
110
|
+
# :created_at => :datetime
|
|
111
|
+
#}
|
|
112
|
+
# EOS
|
|
113
|
+
#
|
|
114
|
+
# end
|
|
115
|
+
# end
|
|
116
|
+
# end
|
|
117
|
+
#end
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
|
+
require 'bigdecimal'
|
|
3
|
+
require 'rational'
|
|
4
|
+
|
|
5
|
+
describe "AwesomeDump" do
|
|
6
|
+
before(:each) do
|
|
7
|
+
stub_dotfile!
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe "Array" do
|
|
11
|
+
before(:each) do
|
|
12
|
+
@arr = [ 1, :two, "three", [ nil, [ true, false] ] ]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "empty array" do
|
|
16
|
+
[].ad.should == []
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "default" do
|
|
20
|
+
@arr.ad.should == [ 1, :two, "three", [ nil, [ true, false ] ] ]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "safe-escaped" do
|
|
24
|
+
@arr.ad(:escape => :safe).should == [1, ':two', "three", [nil, [true, false]]]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "quote-escape" do
|
|
28
|
+
@arr.ad(:escape => :quote).should == ['1', ':two', '"three"', ['nil', ['true', 'false']]]
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "Nested Array" do
|
|
33
|
+
before(:each) do
|
|
34
|
+
@arr = [ 1, 2 ]
|
|
35
|
+
@arr << @arr
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "default" do
|
|
39
|
+
d = [1, 2, ['...']]
|
|
40
|
+
@arr.ad.should == d
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "safe-escaped" do
|
|
44
|
+
d = [1, 2, ['...']]
|
|
45
|
+
@arr.ad(:escape => :safe).should == d
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "quote-escape" do
|
|
49
|
+
d = ['1', '2', ['...']]
|
|
50
|
+
@arr.ad(:escape => :quote).should == d
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
describe "Hash" do
|
|
55
|
+
before(:each) do
|
|
56
|
+
@hash = { 1 => { :sym => { "str" => { [1, 2, 3] => { {:k => :v} => Hash } } } } }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "empty hash" do
|
|
60
|
+
{}.ad.should == {}
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "default" do
|
|
64
|
+
d = { 1 => { :sym => { "str" => { [1, 2, 3] => { {:k => :v} => Hash } } } } }
|
|
65
|
+
@hash.ad.should == d
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "safe-escaped" do
|
|
69
|
+
d = { 1 => { ':sym' => { "str" => { [1, 2, 3] => { {':k' => ':v'} => 'Hash' } } } } }
|
|
70
|
+
@hash.ad(:escape => :safe).should == d
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "quote-escape" do
|
|
74
|
+
d = { '1' => { ':sym' => { '"str"' => { ['1', '2', '3'] => { {':k' => ':v'} => 'Hash' } } } } }
|
|
75
|
+
@hash.ad(:escape => :quote).should == d
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
describe "Nested Hash" do
|
|
81
|
+
before(:each) do
|
|
82
|
+
@hash = {}
|
|
83
|
+
@hash[:a] = @hash
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "default" do
|
|
87
|
+
d = { :a => {'...' => '...'} }
|
|
88
|
+
@hash.ad.should == d
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "safe-escaped" do
|
|
92
|
+
d = { ':a' => {'...' => '...'} }
|
|
93
|
+
@hash.ad(:escape => :safe).should == d
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "quote-escape" do
|
|
97
|
+
d = { ':a' => {'...' => '...'} }
|
|
98
|
+
@hash.ad(:escape => :quote).should == d
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
describe "Class" do
|
|
103
|
+
it "shoud show superclass (quote-escape)" do
|
|
104
|
+
Fixnum.ad(:escape => :quote).should == 'Fixnum < Integer'
|
|
105
|
+
Class.ad(:escape => :quote).should == 'Class < Module'
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
describe "File" do
|
|
110
|
+
it "should display a file (default)" do
|
|
111
|
+
File.open(__FILE__, 'r') do |f|
|
|
112
|
+
f.ad.should == "#{f.inspect}\n" << `ls -alF #{f.path}`.chop
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
describe "Dir" do
|
|
118
|
+
it "should display a directory (default)" do
|
|
119
|
+
Dir.open(File.dirname(__FILE__)) do |d|
|
|
120
|
+
d.ad.should == "#{d.inspect}\n" << `ls -alF #{d.path}`.chop
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
describe "BigDecimal and Rational" do
|
|
126
|
+
it "should present BigDecimal object as Float scalar" do
|
|
127
|
+
big = BigDecimal("2010.4")
|
|
128
|
+
big.ad.should == "2010.4"
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it "should present Rational object as Float scalar" do
|
|
132
|
+
rat = Rational(2010, 2)
|
|
133
|
+
rat.ad.should == "1005.0"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
describe "Utility methods" do
|
|
138
|
+
it "should merge options" do
|
|
139
|
+
ad = AwesomeDump.new
|
|
140
|
+
ad.send(:merge_options!, { :color => { :array => :black }, :indent => 0 })
|
|
141
|
+
options = ad.instance_variable_get("@options")
|
|
142
|
+
options[:color][:array].should == :black
|
|
143
|
+
options[:indent].should == 0
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
describe "Struct" do
|
|
149
|
+
before(:each) do
|
|
150
|
+
@struct = unless defined?(Struct::SimpleStruct)
|
|
151
|
+
Struct.new('SimpleStruct', :name, :address).new
|
|
152
|
+
else
|
|
153
|
+
Struct::SimpleStruct.new
|
|
154
|
+
end
|
|
155
|
+
@struct.name = 'Herman Munster'
|
|
156
|
+
@struct.address = '1313 Mockingbird Lane'
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "empty struct" do
|
|
160
|
+
empty_struct = Struct.new('EmptyStruct').new
|
|
161
|
+
empty_struct.ad.should == {:class => Struct::EmptyStruct, :object_id => empty_struct.object_id}
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it "default" do
|
|
165
|
+
d = {:class => Struct::SimpleStruct, :object_id => @struct.object_id, :address => '1313 Mockingbird Lane', :name => 'Herman Munster'}
|
|
166
|
+
@struct.ad.should == d
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it "safe-escaped" do
|
|
170
|
+
d = {'class' => 'Struct::SimpleStruct', 'object_id' => @struct.object_id, 'address' => '1313 Mockingbird Lane', 'name' => 'Herman Munster'}
|
|
171
|
+
@struct.ad(:escape => :safe).should == d
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it "quote-escaped" do
|
|
175
|
+
d = {'class' => 'Struct::SimpleStruct', 'object_id' => @struct.object_id.to_s, 'address' => '"1313 Mockingbird Lane"', 'name' => '"Herman Munster"'}
|
|
176
|
+
@struct.ad(:escape => :quote).should == d
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
describe "Some Random Object" do
|
|
181
|
+
before(:each) do
|
|
182
|
+
class SomeRandomObject
|
|
183
|
+
def initialize
|
|
184
|
+
@str = 'blah'
|
|
185
|
+
@int = 5
|
|
186
|
+
@arr = ['a', 3]
|
|
187
|
+
@hash = {:hi => 5, 'lo' => Object.new}
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
@object = SomeRandomObject.new
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it "default" do
|
|
194
|
+
d = { :class => SomeRandomObject, :object_id => @object.object_id,
|
|
195
|
+
:'@str' => 'blah',
|
|
196
|
+
:'@int' => 5,
|
|
197
|
+
:'@arr' => ['a', 3],
|
|
198
|
+
:'@hash' => {
|
|
199
|
+
:hi => 5,
|
|
200
|
+
'lo' => {:class => Object, :object_id => @object.instance_variable_get(:'@hash')['lo'].object_id}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
@object.ad.should == d
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it "safe-escaped" do
|
|
207
|
+
d = { 'class' => 'SomeRandomObject', 'object_id' => @object.object_id,
|
|
208
|
+
'@str' => 'blah',
|
|
209
|
+
'@int' => 5,
|
|
210
|
+
'@arr' => ['a', 3],
|
|
211
|
+
'@hash' => {
|
|
212
|
+
':hi' => 5,
|
|
213
|
+
'lo' => {'class' => 'Object', 'object_id' => @object.instance_variable_get(:'@hash')['lo'].object_id}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
@object.ad(:escape => :safe).should == d
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
it "quote-escaped" do
|
|
220
|
+
d = { 'class' => 'SomeRandomObject', 'object_id' => @object.object_id.to_s,
|
|
221
|
+
'@str' => '"blah"',
|
|
222
|
+
'@int' => '5',
|
|
223
|
+
'@arr' => ['"a"', '3'],
|
|
224
|
+
'@hash' => {
|
|
225
|
+
':hi' => '5',
|
|
226
|
+
'"lo"' => {'class' => 'Object', 'object_id' => @object.instance_variable_get(:'@hash')['lo'].object_id.to_s}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
@object.ad(:escape => :quote).should == d
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
end
|
data/spec/logger_spec.rb
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
require 'logger'
|
|
5
|
+
require 'ad/core_ext/logger'
|
|
6
|
+
|
|
7
|
+
describe "AwesomeDump logging extensions" do
|
|
8
|
+
before(:all) do
|
|
9
|
+
@logger = Logger.new('/dev/null')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe "ad method" do
|
|
13
|
+
it "should awesome_inspect the given object" do
|
|
14
|
+
object = mock
|
|
15
|
+
object.should_receive(:ad)
|
|
16
|
+
@logger.ad object
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe "the log level" do
|
|
20
|
+
before(:each) do
|
|
21
|
+
AwesomeDump.defaults = { }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should fallback to the default :debug log level" do
|
|
25
|
+
@logger.should_receive(:debug)
|
|
26
|
+
@logger.ad(nil)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should use the global user default if no level passed" do
|
|
30
|
+
AwesomeDump.defaults = { :log_level => :info }
|
|
31
|
+
@logger.should_receive(:info)
|
|
32
|
+
@logger.ad(nil)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should use the passed in level" do
|
|
36
|
+
@logger.should_receive(:warn)
|
|
37
|
+
@logger.ad(nil, :warn)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
data/spec/spec.opts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
3
|
+
require 'ad'
|
|
4
|
+
require 'spec'
|
|
5
|
+
require 'spec/autorun'
|
|
6
|
+
require 'rubygems'
|
|
7
|
+
|
|
8
|
+
Spec::Runner.configure do |config|
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def stub_dotfile!
|
|
12
|
+
dotfile = File.join(ENV["HOME"], ".adrc")
|
|
13
|
+
File.should_receive(:readable?).at_least(:once).with(dotfile).and_return(false)
|
|
14
|
+
end
|
data/spec/string_spec.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
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
|
+
"pale".send(:pale).should == "\e[0;37mpale\e[0m"
|
|
18
|
+
"whiteish".send(:whiteish).should == "\e[0;37mwhiteish\e[0m"
|
|
19
|
+
end
|
|
20
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: awesome_dump
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 29
|
|
5
|
+
prerelease:
|
|
6
|
+
segments:
|
|
7
|
+
- 0
|
|
8
|
+
- 0
|
|
9
|
+
- 1
|
|
10
|
+
version: 0.0.1
|
|
11
|
+
platform: ruby
|
|
12
|
+
authors:
|
|
13
|
+
- Michael Dvorkin
|
|
14
|
+
autorequire:
|
|
15
|
+
bindir: bin
|
|
16
|
+
cert_chain: []
|
|
17
|
+
|
|
18
|
+
date: 2011-02-20 00:00:00 -08:00
|
|
19
|
+
default_executable:
|
|
20
|
+
dependencies:
|
|
21
|
+
- !ruby/object:Gem::Dependency
|
|
22
|
+
name: rspec
|
|
23
|
+
prerelease: false
|
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
hash: 13
|
|
30
|
+
segments:
|
|
31
|
+
- 1
|
|
32
|
+
- 2
|
|
33
|
+
- 9
|
|
34
|
+
version: 1.2.9
|
|
35
|
+
type: :development
|
|
36
|
+
version_requirements: *id001
|
|
37
|
+
description: "Great Ruby dubugging companion: pretty print Ruby objects to visualize their structure. Supports Rails ActiveRecord objects via included mixin."
|
|
38
|
+
email: mike@dvorkin.net
|
|
39
|
+
executables: []
|
|
40
|
+
|
|
41
|
+
extensions: []
|
|
42
|
+
|
|
43
|
+
extra_rdoc_files:
|
|
44
|
+
- LICENSE
|
|
45
|
+
- README.md
|
|
46
|
+
files:
|
|
47
|
+
- CHANGELOG
|
|
48
|
+
- LICENSE
|
|
49
|
+
- README.md
|
|
50
|
+
- Rakefile
|
|
51
|
+
- VERSION
|
|
52
|
+
- init.rb
|
|
53
|
+
- lib/ad.rb
|
|
54
|
+
- lib/ad/awesome_dump.rb
|
|
55
|
+
- lib/ad/core_ext/kernel.rb
|
|
56
|
+
- lib/ad/core_ext/logger.rb
|
|
57
|
+
- lib/ad/core_ext/string.rb
|
|
58
|
+
- lib/ad/mixin/active_record.rb
|
|
59
|
+
- lib/ad/mixin/active_support.rb
|
|
60
|
+
- rails/init.rb
|
|
61
|
+
- spec/active_record_spec.rb
|
|
62
|
+
- spec/awesome_dump_spec.rb
|
|
63
|
+
- spec/logger_spec.rb
|
|
64
|
+
- spec/spec.opts
|
|
65
|
+
- spec/spec_helper.rb
|
|
66
|
+
- spec/string_spec.rb
|
|
67
|
+
has_rdoc: true
|
|
68
|
+
homepage: http://github.com/slippyd/awesome_dump
|
|
69
|
+
licenses: []
|
|
70
|
+
|
|
71
|
+
post_install_message:
|
|
72
|
+
rdoc_options: []
|
|
73
|
+
|
|
74
|
+
require_paths:
|
|
75
|
+
- lib
|
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
77
|
+
none: false
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
hash: 3
|
|
82
|
+
segments:
|
|
83
|
+
- 0
|
|
84
|
+
version: "0"
|
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
|
+
none: false
|
|
87
|
+
requirements:
|
|
88
|
+
- - ">="
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
hash: 3
|
|
91
|
+
segments:
|
|
92
|
+
- 0
|
|
93
|
+
version: "0"
|
|
94
|
+
requirements: []
|
|
95
|
+
|
|
96
|
+
rubyforge_project: awesome_dump
|
|
97
|
+
rubygems_version: 1.5.2
|
|
98
|
+
signing_key:
|
|
99
|
+
specification_version: 3
|
|
100
|
+
summary: Pretty print Ruby objects with proper indentation and colors.
|
|
101
|
+
test_files:
|
|
102
|
+
- spec/active_record_spec.rb
|
|
103
|
+
- spec/awesome_dump_spec.rb
|
|
104
|
+
- spec/logger_spec.rb
|
|
105
|
+
- spec/spec_helper.rb
|
|
106
|
+
- spec/string_spec.rb
|