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.
@@ -0,0 +1,3 @@
1
+ 0.0.1
2
+ - WIP port from the awesome_print project.
3
+
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.
@@ -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.
@@ -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")
@@ -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)
@@ -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
@@ -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
+
@@ -0,0 +1 @@
1
+ --color
@@ -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
@@ -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