From 2105efbf51f2cc3888d4eefceae5b93d038c000c Mon Sep 17 00:00:00 2001 From: James Cox Date: Tue, 22 Jan 2019 11:01:43 -0500 Subject: [PATCH] New approach for awesomeprint -- this uses a factory pattern to register formatters as they go. wip. --- .gitignore | 1 + .rspec | 1 + .travis.yml | 4 +- CHANGELOG.md | 2 + awesome_print.gemspec | 2 + lib/awesome_print.rb | 36 ++--- lib/awesome_print/colorize.rb | 2 + lib/awesome_print/ext/ostruct.rb | 27 ---- lib/awesome_print/formatter.rb | 137 ++++-------------- .../formatters/array_formatter.rb | 17 ++- .../formatters/base_formatter.rb | 65 ++------- .../formatters/bigdecimal_formatter.rb | 19 +++ .../formatters/class_formatter.rb | 11 +- lib/awesome_print/formatters/dir_formatter.rb | 10 +- .../formatters/fallback_formatter.rb | 51 +++++++ .../formatters/false_class_formatter.rb | 15 ++ .../formatters/file_formatter.rb | 10 +- .../formatters/hash_formatter.rb | 17 ++- .../formatters/integer_formatter.rb | 11 ++ .../formatters/method_formatter.rb | 11 +- .../formatters/nil_class_formatter.rb | 19 +++ .../formatters/object_formatter.rb | 16 +- lib/awesome_print/formatters/open_struct.rb | 19 +++ .../formatters/rational_formatter.rb | 11 ++ .../formatters/simple_formatter.rb | 14 +- .../formatters/string_formatter.rb | 11 ++ .../formatters/struct_formatter.rb | 16 +- .../formatters/symbol_formatter.rb | 18 +++ .../formatters/true_class_formatter.rb | 15 ++ lib/awesome_print/inspector.rb | 17 +-- lib/awesome_print/limiter.rb | 63 ++++++++ lib/awesome_print/registrar.rb | 20 +++ spec/ext/ostruct_spec.rb | 1 + spec/formats_spec.rb | 2 +- spec/spec_helper.rb | 2 + 35 files changed, 418 insertions(+), 275 deletions(-) delete mode 100644 lib/awesome_print/ext/ostruct.rb create mode 100644 lib/awesome_print/formatters/bigdecimal_formatter.rb create mode 100644 lib/awesome_print/formatters/fallback_formatter.rb create mode 100644 lib/awesome_print/formatters/false_class_formatter.rb create mode 100644 lib/awesome_print/formatters/integer_formatter.rb create mode 100644 lib/awesome_print/formatters/nil_class_formatter.rb create mode 100644 lib/awesome_print/formatters/open_struct.rb create mode 100644 lib/awesome_print/formatters/rational_formatter.rb create mode 100644 lib/awesome_print/formatters/string_formatter.rb create mode 100644 lib/awesome_print/formatters/symbol_formatter.rb create mode 100644 lib/awesome_print/formatters/true_class_formatter.rb create mode 100644 lib/awesome_print/limiter.rb create mode 100644 lib/awesome_print/registrar.rb diff --git a/.gitignore b/.gitignore index 9a3813e..5ac8425 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ Gemfile.lock # PROJECT::RBENV .ruby-gemset .awesome-print/ +.byebug_history diff --git a/.rspec b/.rspec index 4e1e0d2..b7afd2d 100644 --- a/.rspec +++ b/.rspec @@ -1 +1,2 @@ +--format Fuubar --color diff --git a/.travis.yml b/.travis.yml index 5d9a377..c662e7c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,8 +24,8 @@ matrix: include: - rvm: ruby-head env: RUBYOPT="--enable-frozen-string-literal" - # allow_failures: - # - rvm: ruby-head + allow_failures: + - rvm: ruby-head addons: code_climate: diff --git a/CHANGELOG.md b/CHANGELOG.md index 597aff8..6a68462 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,6 @@ ## master (unreleased) + +## 2.0.0 - Fixes spec suite to properly work via travis, gets a clean build [@imajes, others] - Adds support for ActiveModel::Errors [@dshinzie] - [#301] - removes use of `strip_heredoc` from specs as it's a rails dep [@kstephens] - [#303] diff --git a/awesome_print.gemspec b/awesome_print.gemspec index 25cce46..735a7ea 100644 --- a/awesome_print.gemspec +++ b/awesome_print.gemspec @@ -24,7 +24,9 @@ Gem::Specification.new do |s| s.require_paths = ['lib'] s.add_development_dependency 'rspec', '>= 3.0.0' + s.add_development_dependency 'fuubar' s.add_development_dependency 'appraisal' + s.add_development_dependency 'byebug' s.add_development_dependency 'fakefs', '>= 0.2.1' s.add_development_dependency 'sqlite3' s.add_development_dependency 'nokogiri', '>= 1.6.5' diff --git a/lib/awesome_print.rb b/lib/awesome_print.rb index 06358a6..eeaa7a4 100644 --- a/lib/awesome_print.rb +++ b/lib/awesome_print.rb @@ -15,27 +15,29 @@ unless defined?(AwesomePrint::Inspector) require 'awesome_print/custom_defaults' require 'awesome_print/inspector' require 'awesome_print/formatter' + Dir["./lib/awesome_print/formatters/**/*.rb"].each { |f| require f } + require 'awesome_print/version' require 'awesome_print/core_ext/logger' if defined?(Logger) # # Load the following under normal circumstances as well as in Rails # console when required from ~/.irbrc or ~/.pryrc. # - require 'awesome_print/ext/active_record' if defined?(ActiveRecord) || AwesomePrint.rails_console? - require 'awesome_print/ext/active_support' if defined?(ActiveSupport) || AwesomePrint.rails_console? - # - # Load remaining extensions. - # - if defined?(ActiveSupport.on_load) - ActiveSupport.on_load(:action_view) do - require 'awesome_print/ext/action_view' - end - end - require 'awesome_print/ext/mongo_mapper' if defined?(MongoMapper) - require 'awesome_print/ext/mongoid' if defined?(Mongoid) - require 'awesome_print/ext/nokogiri' if defined?(Nokogiri) - require 'awesome_print/ext/nobrainer' if defined?(NoBrainer) - require 'awesome_print/ext/ripple' if defined?(Ripple) - require 'awesome_print/ext/sequel' if defined?(Sequel) - require 'awesome_print/ext/ostruct' if defined?(OpenStruct) + # require 'awesome_print/ext/active_record' if defined?(ActiveRecord) || AwesomePrint.rails_console? + # require 'awesome_print/ext/active_support' if defined?(ActiveSupport) || AwesomePrint.rails_console? + # # + # # Load remaining extensions. + # # + # if defined?(ActiveSupport.on_load) + # ActiveSupport.on_load(:action_view) do + # require 'awesome_print/ext/action_view' + # end + # end + # require 'awesome_print/ext/mongo_mapper' if defined?(MongoMapper) + # require 'awesome_print/ext/mongoid' if defined?(Mongoid) + # require 'awesome_print/ext/nokogiri' if defined?(Nokogiri) + # require 'awesome_print/ext/nobrainer' if defined?(NoBrainer) + # require 'awesome_print/ext/ripple' if defined?(Ripple) + # require 'awesome_print/ext/sequel' if defined?(Sequel) + # require 'awesome_print/ext/ostruct' if defined?(OpenStruct) end diff --git a/lib/awesome_print/colorize.rb b/lib/awesome_print/colorize.rb index f9adaf1..70e3335 100644 --- a/lib/awesome_print/colorize.rb +++ b/lib/awesome_print/colorize.rb @@ -6,6 +6,8 @@ module AwesomePrint # Pick the color and apply it to the given string as necessary. #------------------------------------------------------------------------------ def colorize(str, type) + puts "[COLORIZING] - using #{options[:color][type]} for #{type}" + str = CGI.escapeHTML(str) if options[:html] if options[:plain] || !options[:color][type] || !inspector.colorize? str diff --git a/lib/awesome_print/ext/ostruct.rb b/lib/awesome_print/ext/ostruct.rb deleted file mode 100644 index 0d89819..0000000 --- a/lib/awesome_print/ext/ostruct.rb +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2010-2016 Michael Dvorkin and contributors -# -# Awesome Print is freely distributable under the terms of MIT license. -# See LICENSE file or http://www.opensource.org/licenses/mit-license.php -#------------------------------------------------------------------------------ -module AwesomePrint - module OpenStruct - def self.included(base) - base.send :alias_method, :cast_without_ostruct, :cast - base.send :alias_method, :cast, :cast_with_ostruct - end - - def cast_with_ostruct(object, type) - cast = cast_without_ostruct(object, type) - if (defined?(::OpenStruct)) && (object.is_a?(::OpenStruct)) - cast = :open_struct_instance - end - cast - end - - def awesome_open_struct_instance(object) - "#{object.class} #{awesome_hash(object.marshal_dump)}" - end - end -end - -AwesomePrint::Formatter.send(:include, AwesomePrint::OpenStruct) diff --git a/lib/awesome_print/formatter.rb b/lib/awesome_print/formatter.rb index 5090138..49cae34 100644 --- a/lib/awesome_print/formatter.rb +++ b/lib/awesome_print/formatter.rb @@ -1,126 +1,53 @@ -# Copyright (c) 2010-2016 Michael Dvorkin and contributors -# -# Awesome Print is freely distributable under the terms of MIT license. -# See LICENSE file or http://www.opensource.org/licenses/mit-license.php -#------------------------------------------------------------------------------ -require 'awesome_print/formatters' +require_relative 'colorize' module AwesomePrint class Formatter + include Colorize attr_reader :inspector, :options - CORE_FORMATTERS = [:array, :bigdecimal, :class, :dir, :file, :hash, :method, :rational, :set, :struct, :unboundmethod] + # Acts as a class ivar + @registered_formatters = {} + + # make it accessible + def self.registered_formatters + @registered_formatters + end + + # register a new formatter.. + #------------------------------------------------------------------------------ + def self.register(formatter) + @registered_formatters[formatter.formatted_object_type.to_sym] = formatter + end def initialize(inspector) - @inspector = inspector - @options = inspector.options + @inspector = inspector + @options = inspector.options end + # Main entry point to format an object. + # type is determined by Inspector#printable #------------------------------------------------------------------------------ def format(object, type = nil) - core_class = cast(object, type) - awesome = if core_class != :self - send(:"awesome_#{core_class}", object) # Core formatters. + puts "[FORMAT] #{type.to_s.red} >>> #{object}" + + format_with = active_formatter(type) + puts "[ACTIVE] using > #{format_with.to_s.blueish} < to format" + + if format_with && format_with.send(:formattable?, object) + format_with.new(@inspector).format(object) else - awesome_self(object, type) # Catch all that falls back to object.inspect. - end - awesome - end - - # Hook this when adding custom formatters. Check out lib/awesome_print/ext - # directory for custom formatters that ship with awesome_print. - #------------------------------------------------------------------------------ - def cast(object, type) - CORE_FORMATTERS.include?(type) ? type : :self - end - - private - - # Catch all method to format an arbitrary object. - #------------------------------------------------------------------------------ - def awesome_self(object, type) - if @options[:raw] && object.instance_variables.any? - awesome_object(object) - elsif (hash = convert_to_hash(object)) - awesome_hash(hash) - else - awesome_simple(object.inspect.to_s, type, @inspector) + puts "[FALLBACK] well darn, we're just gonna have to fb" + # in this case, formatter is missing or fails format test + AwesomePrint::Formatters::FallbackFormatter.new(@inspector).format(object) end end - def awesome_bigdecimal(n) - o = n.to_s('F') - type = :bigdecimal - awesome_simple(o, type, @inspector) - end - - def awesome_rational(n) - o = n.to_s - type = :rational - awesome_simple(o, type, @inspector) - end - - def awesome_simple(o, type, inspector = @inspector) - AwesomePrint::Formatters::SimpleFormatter.new(o, type, inspector).format - end - - def awesome_array(a) - Formatters::ArrayFormatter.new(a, @inspector).format - end - - def awesome_set(s) - Formatters::ArrayFormatter.new(s.to_a, @inspector).format - end - - def awesome_hash(h) - Formatters::HashFormatter.new(h, @inspector).format - end - - def awesome_object(o) - Formatters::ObjectFormatter.new(o, @inspector).format - end - - def awesome_struct(s) - Formatters::StructFormatter.new(s, @inspector).format - end - - def awesome_method(m) - Formatters::MethodFormatter.new(m, @inspector).format - end - alias :awesome_unboundmethod :awesome_method - - def awesome_class(c) - Formatters::ClassFormatter.new(c, @inspector).format - end - - def awesome_file(f) - Formatters::FileFormatter.new(f, @inspector).format - end - - def awesome_dir(d) - Formatters::DirFormatter.new(d, @inspector).format - end - - # Utility methods. - #------------------------------------------------------------------------------ - def convert_to_hash(object) - if !object.respond_to?(:to_hash) - return nil - end - - if object.method(:to_hash).arity != 0 - return nil - end - - hash = object.to_hash - if !hash.respond_to?(:keys) || !hash.respond_to?('[]') - return nil - end - - return hash + def active_formatter(type) + self.class.registered_formatters[type] end end end + diff --git a/lib/awesome_print/formatters/array_formatter.rb b/lib/awesome_print/formatters/array_formatter.rb index 3340a77..5381594 100644 --- a/lib/awesome_print/formatters/array_formatter.rb +++ b/lib/awesome_print/formatters/array_formatter.rb @@ -3,16 +3,19 @@ require_relative 'base_formatter' module AwesomePrint module Formatters class ArrayFormatter < BaseFormatter - attr_reader :array, :inspector, :options - def initialize(array, inspector) - @array = array - @inspector = inspector - @options = inspector.options + formatter_for :array + + def self.formattable?(object) + object.is_a?(Array) end - def format - if array.length.zero? + attr_reader :array + + def format(object) + @array = object + + if object.length.zero? '[]' elsif methods_array? methods_array diff --git a/lib/awesome_print/formatters/base_formatter.rb b/lib/awesome_print/formatters/base_formatter.rb index c7f71c6..61897a1 100644 --- a/lib/awesome_print/formatters/base_formatter.rb +++ b/lib/awesome_print/formatters/base_formatter.rb @@ -1,68 +1,26 @@ require_relative '../colorize' +require_relative '../limiter' +require_relative '../registrar' module AwesomePrint module Formatters class BaseFormatter + include Colorize + include Registrar + include Limiter - DEFAULT_LIMIT_SIZE = 7 + attr_reader :object, :inspector, :options - # To support limited output, for example: - # - # ap ('a'..'z').to_a, :limit => 3 - # [ - # [ 0] "a", - # [ 1] .. [24], - # [25] "z" - # ] - # - # ap (1..100).to_a, :limit => true # Default limit is 7. - # [ - # [ 0] 1, - # [ 1] 2, - # [ 2] 3, - # [ 3] .. [96], - # [97] 98, - # [98] 99, - # [99] 100 - # ] - #------------------------------------------------------------------------------ - def should_be_limited? - options[:limit] or (options[:limit].is_a?(Integer) and options[:limit] > 0) + def initialize(inspector) + @inspector = inspector + @options = inspector.options end - def get_limit_size - case options[:limit] - when true - DEFAULT_LIMIT_SIZE - else - options[:limit] - end + def format(object) + raise NotImplementedError end - def limited(data, width, is_hash = false) - limit = get_limit_size - if data.length <= limit - data - else - # Calculate how many elements to be displayed above and below the separator. - head = limit / 2 - tail = head - (limit - 1) % 2 - - # Add the proper elements to the temp array and format the separator. - temp = data[0, head] + [nil] + data[-tail, tail] - - temp[head] = if is_hash - "#{indent}#{data[head].strip} .. #{data[data.length - tail - 1].strip}" - else - "#{indent}[#{head.to_s.rjust(width)}] .. [#{data.length - tail - 1}]" - end - - temp - end - end - - def method_tuple(method) if method.respond_to?(:parameters) # Ruby 1.9.2+ # See http://readruby.chengguangnan.com/methods#method-objects-parameters @@ -104,6 +62,7 @@ module AwesomePrint # # Indentation related methods + # FIXME: move to Indentator?... #----------------------------------------- def indentation inspector.current_indentation diff --git a/lib/awesome_print/formatters/bigdecimal_formatter.rb b/lib/awesome_print/formatters/bigdecimal_formatter.rb new file mode 100644 index 0000000..a626b93 --- /dev/null +++ b/lib/awesome_print/formatters/bigdecimal_formatter.rb @@ -0,0 +1,19 @@ +require_relative 'base_formatter' + +module AwesomePrint + module Formatters + class BigdecimalFormatter < BaseFormatter + + formatter_for :bigdecimal + + def self.formattable?(object) + true + end + + def format(object) + colorize(object.to_s('F'), self.class.formatted_object_type) + end + + end + end +end diff --git a/lib/awesome_print/formatters/class_formatter.rb b/lib/awesome_print/formatters/class_formatter.rb index d5082ea..417aced 100644 --- a/lib/awesome_print/formatters/class_formatter.rb +++ b/lib/awesome_print/formatters/class_formatter.rb @@ -4,16 +4,15 @@ module AwesomePrint module Formatters class ClassFormatter < BaseFormatter - attr_reader :klass, :inspector, :options + formatter_for :class - def initialize(klass, inspector) - @klass = klass - @inspector = inspector - @options = inspector.options + def self.formattable?(object) + object.is_a?(Class) end - def format + def format(klass) superclass = klass.superclass + if superclass colorize("#{klass.inspect} < #{superclass}", :class) else diff --git a/lib/awesome_print/formatters/dir_formatter.rb b/lib/awesome_print/formatters/dir_formatter.rb index 0b1bc7b..69bff1d 100644 --- a/lib/awesome_print/formatters/dir_formatter.rb +++ b/lib/awesome_print/formatters/dir_formatter.rb @@ -5,15 +5,13 @@ module AwesomePrint module Formatters class DirFormatter < BaseFormatter - attr_reader :dir, :inspector, :options + formatter_for :dir - def initialize(dir, inspector) - @dir = dir - @inspector = inspector - @options = inspector.options + def self.formattable?(object) + object.is_a?(Dir) end - def format + def format(dir) ls = `ls -alF #{dir.path.shellescape}` colorize(ls.empty? ? dir.inspect : "#{dir.inspect}\n#{ls.chop}", :dir) end diff --git a/lib/awesome_print/formatters/fallback_formatter.rb b/lib/awesome_print/formatters/fallback_formatter.rb new file mode 100644 index 0000000..083e298 --- /dev/null +++ b/lib/awesome_print/formatters/fallback_formatter.rb @@ -0,0 +1,51 @@ +require_relative 'base_formatter' + +# this handles some fallback logic to route things we don't know what they are + +module AwesomePrint + module Formatters + class FallbackFormatter < BaseFormatter + + formatter_for :self + + def self.formattable?(object) + true + end + + def format(object) + if @options[:raw] && object.instance_variables.any? + Formatters::ObjectFormatter.new(@inspector).format(object) + elsif (hash = convert_to_hash(object)) + Formatters::HashFormatter.new(@inspector).format(hash) + else + Formatters::SimpleFormatter.new(@inspector).format(object.inspect.to_s) + end + end + + + private + + # Utility methods. + #------------------------------------------------------------------------------ + # FIXME: this could be super fixed. + # + def convert_to_hash(object) + if !object.respond_to?(:to_hash) + return nil + end + + if object.method(:to_hash).arity != 0 + return nil + end + + hash = object.to_hash + if !hash.respond_to?(:keys) || !hash.respond_to?('[]') + return nil + end + + return hash + end + + end + end +end diff --git a/lib/awesome_print/formatters/false_class_formatter.rb b/lib/awesome_print/formatters/false_class_formatter.rb new file mode 100644 index 0000000..f069cf4 --- /dev/null +++ b/lib/awesome_print/formatters/false_class_formatter.rb @@ -0,0 +1,15 @@ +require_relative 'simple_formatter' + +module AwesomePrint + module Formatters + class FalseClassFormatter < SimpleFormatter + + formatter_for :falseclass + + def self.formattable?(object) + object == false + end + + end + end +end diff --git a/lib/awesome_print/formatters/file_formatter.rb b/lib/awesome_print/formatters/file_formatter.rb index 68c59da..10d97e4 100644 --- a/lib/awesome_print/formatters/file_formatter.rb +++ b/lib/awesome_print/formatters/file_formatter.rb @@ -5,15 +5,13 @@ module AwesomePrint module Formatters class FileFormatter < BaseFormatter - attr_reader :file, :inspector, :options + formatter_for :file - def initialize(file, inspector) - @file = file - @inspector = inspector - @options = inspector.options + def self.formattable?(object) + object.is_a?(File) end - def format + def format(file) ls = File.directory?(file) ? `ls -adlF #{file.path.shellescape}` : `ls -alF #{file.path.shellescape}` colorize(ls.empty? ? file.inspect : "#{file.inspect}\n#{ls.chop}", :file) end diff --git a/lib/awesome_print/formatters/hash_formatter.rb b/lib/awesome_print/formatters/hash_formatter.rb index c29bb63..9228cf0 100644 --- a/lib/awesome_print/formatters/hash_formatter.rb +++ b/lib/awesome_print/formatters/hash_formatter.rb @@ -3,15 +3,20 @@ require_relative 'base_formatter' module AwesomePrint module Formatters class HashFormatter < BaseFormatter - attr_reader :hash, :inspector, :options - def initialize(hash, inspector) - @hash = hash - @inspector = inspector - @options = inspector.options + attr_reader :hash + + formatter_for :hash + + def self.formattable?(object) + object.is_a?(Hash) end - def format + # INSTANCE METHODS BELOW + + def format(hash) + @hash = hash + if hash.empty? empty_hash elsif multiline_hash? diff --git a/lib/awesome_print/formatters/integer_formatter.rb b/lib/awesome_print/formatters/integer_formatter.rb new file mode 100644 index 0000000..b69cef1 --- /dev/null +++ b/lib/awesome_print/formatters/integer_formatter.rb @@ -0,0 +1,11 @@ +require_relative 'simple_formatter' + +module AwesomePrint + module Formatters + class IntegerFormatter < SimpleFormatter + + formatter_for :integer + + end + end +end diff --git a/lib/awesome_print/formatters/method_formatter.rb b/lib/awesome_print/formatters/method_formatter.rb index 26c398d..a61312f 100644 --- a/lib/awesome_print/formatters/method_formatter.rb +++ b/lib/awesome_print/formatters/method_formatter.rb @@ -4,15 +4,14 @@ module AwesomePrint module Formatters class MethodFormatter < BaseFormatter - attr_reader :method, :inspector, :options + formatter_for :method - def initialize(method, inspector) - @method = method - @inspector = inspector - @options = inspector.options + def self.formattable?(object) + puts "formattable? for METHOD..." + true end - def format + def format(method) name, args, owner = method_tuple(method) "#{colorize(owner, :class)}##{colorize(name, :method)}#{colorize(args, :args)}" diff --git a/lib/awesome_print/formatters/nil_class_formatter.rb b/lib/awesome_print/formatters/nil_class_formatter.rb new file mode 100644 index 0000000..5abf5cf --- /dev/null +++ b/lib/awesome_print/formatters/nil_class_formatter.rb @@ -0,0 +1,19 @@ +require_relative 'simple_formatter' + +module AwesomePrint + module Formatters + class NilClassFormatter < SimpleFormatter + + formatter_for :nilclass + + def self.formattable?(object) + object == nil + end + + def format(object) + colorize('nil', self.class.formatted_object_type) + end + + end + end +end diff --git a/lib/awesome_print/formatters/object_formatter.rb b/lib/awesome_print/formatters/object_formatter.rb index 49334f7..0b0b344 100644 --- a/lib/awesome_print/formatters/object_formatter.rb +++ b/lib/awesome_print/formatters/object_formatter.rb @@ -4,16 +4,18 @@ module AwesomePrint module Formatters class ObjectFormatter < BaseFormatter - attr_reader :object, :variables, :inspector, :options + formatter_for :object - def initialize(object, inspector) - @object = object - @variables = object.instance_variables - @inspector = inspector - @options = inspector.options + def self.formattable?(object) + object.is_a?(Object) end - def format + attr_reader :variables + + def format(object) + @object = object + @variables = object.instance_variables + vars = variables.map do |var| property = var.to_s[1..-1].to_sym # to_s because of some monkey patching done by Puppet. accessor = if object.respond_to?(:"#{property}=") diff --git a/lib/awesome_print/formatters/open_struct.rb b/lib/awesome_print/formatters/open_struct.rb new file mode 100644 index 0000000..6d9674c --- /dev/null +++ b/lib/awesome_print/formatters/open_struct.rb @@ -0,0 +1,19 @@ +require_relative 'base_formatter' + +module AwesomePrint + module Formatters + class OpenStruct < BaseFormatter + + formatter_for :openstruct + + def self.formattable?(object) + defined?(::OpenStruct) && object.is_a?(::OpenStruct) + end + + def format(object) + "#{object.class} #{HashFormatter.new(inspector).format(object.marshal_dump)}" + end + + end + end +end diff --git a/lib/awesome_print/formatters/rational_formatter.rb b/lib/awesome_print/formatters/rational_formatter.rb new file mode 100644 index 0000000..c91e632 --- /dev/null +++ b/lib/awesome_print/formatters/rational_formatter.rb @@ -0,0 +1,11 @@ +require_relative 'simple_formatter' + +module AwesomePrint + module Formatters + class RationalFormatter < SimpleFormatter + + formatter_for :rational + + end + end +end diff --git a/lib/awesome_print/formatters/simple_formatter.rb b/lib/awesome_print/formatters/simple_formatter.rb index bdd274f..04d403e 100644 --- a/lib/awesome_print/formatters/simple_formatter.rb +++ b/lib/awesome_print/formatters/simple_formatter.rb @@ -4,18 +4,16 @@ module AwesomePrint module Formatters class SimpleFormatter < BaseFormatter - attr_reader :string, :type, :inspector, :options + formatter_for :simple - def initialize(string, type, inspector) - @string = string - @type = type - @inspector = inspector - @options = inspector.options + def self.formattable?(object) + object.respond_to?(:to_s) end - def format - colorize(string, type) + def format(object) + colorize(object.to_s, self.class.formatted_object_type) end + end end end diff --git a/lib/awesome_print/formatters/string_formatter.rb b/lib/awesome_print/formatters/string_formatter.rb new file mode 100644 index 0000000..7beaf62 --- /dev/null +++ b/lib/awesome_print/formatters/string_formatter.rb @@ -0,0 +1,11 @@ +require_relative 'simple_formatter' + +module AwesomePrint + module Formatters + class StringFormatter < SimpleFormatter + + formatter_for :string + + end + end +end diff --git a/lib/awesome_print/formatters/struct_formatter.rb b/lib/awesome_print/formatters/struct_formatter.rb index 18bebaa..66ecf4f 100644 --- a/lib/awesome_print/formatters/struct_formatter.rb +++ b/lib/awesome_print/formatters/struct_formatter.rb @@ -4,16 +4,18 @@ module AwesomePrint module Formatters class StructFormatter < BaseFormatter - attr_reader :struct, :variables, :inspector, :options + formatter_for :struct - def initialize(struct, inspector) - @struct = struct - @variables = struct.members - @inspector = inspector - @options = inspector.options + def self.formattable?(object) + object.is_a?(Struct) end - def format + attr_reader :struct, :variables + + def format(struct) + @struct = struct + @variables = struct.members + vars = variables.map do |var| property = var.to_s[1..-1].to_sym # to_s because of some monkey patching done by Puppet. accessor = if struct.respond_to?(:"#{property}=") diff --git a/lib/awesome_print/formatters/symbol_formatter.rb b/lib/awesome_print/formatters/symbol_formatter.rb new file mode 100644 index 0000000..c97561b --- /dev/null +++ b/lib/awesome_print/formatters/symbol_formatter.rb @@ -0,0 +1,18 @@ +require_relative 'simple_formatter' + +module AwesomePrint + module Formatters + class SymbolFormatter < SimpleFormatter + + formatter_for :symbol + + def self.formattable?(object) + object.respond_to?(:to_s) + end + + def format(object) + colorize(object.to_s, self.class.formatted_object_type) + end + end + end +end diff --git a/lib/awesome_print/formatters/true_class_formatter.rb b/lib/awesome_print/formatters/true_class_formatter.rb new file mode 100644 index 0000000..de46697 --- /dev/null +++ b/lib/awesome_print/formatters/true_class_formatter.rb @@ -0,0 +1,15 @@ +require_relative 'simple_formatter' + +module AwesomePrint + module Formatters + class TrueClassFormatter < SimpleFormatter + + formatter_for :trueclass + + def self.formattable?(object) + object == true + end + + end + end +end diff --git a/lib/awesome_print/inspector.rb b/lib/awesome_print/inspector.rb index 3c3fe11..a98b2d7 100644 --- a/lib/awesome_print/inspector.rb +++ b/lib/awesome_print/inspector.rb @@ -42,6 +42,7 @@ module AwesomePrint rational: :blue, string: :yellowish, struct: :pale, + openstruct: :pale, symbol: :cyanish, time: :greenish, trueclass: :green, @@ -106,9 +107,10 @@ module AwesomePrint #--------------------------------------------------------------------------- def nested(object) case printable(object) - when :array then @formatter.colorize('[...]', :array) - when :hash then @formatter.colorize('{...}', :hash) - when :struct then @formatter.colorize('{...}', :struct) + when :array then @formatter.colorize('[...]', :array) + when :hash then @formatter.colorize('{...}', :hash) + when :struct then @formatter.colorize('{...}', :struct) + when :openstruct then @formatter.colorize('{...}', :openstruct) else @formatter.colorize("...#{object.class}...", :class) end end @@ -123,14 +125,7 @@ module AwesomePrint # base class. #--------------------------------------------------------------------------- def printable(object) - case object - when Array then :array - when Hash then :hash - when File then :file - when Dir then :dir - when Struct then :struct - else object.class.to_s.gsub(/:+/, '_').downcase.to_sym - end + object.class.to_s.gsub(/:+/, '_').downcase.to_sym end # Update @options by first merging the :color hash and then the remaining diff --git a/lib/awesome_print/limiter.rb b/lib/awesome_print/limiter.rb new file mode 100644 index 0000000..4c609b1 --- /dev/null +++ b/lib/awesome_print/limiter.rb @@ -0,0 +1,63 @@ +module AwesomePrint + module Limiter + + DEFAULT_LIMIT_SIZE = 7 + + # To support limited output, for example: + # + # ap ('a'..'z').to_a, :limit => 3 + # [ + # [ 0] "a", + # [ 1] .. [24], + # [25] "z" + # ] + # + # ap (1..100).to_a, :limit => true # Default limit is 7. + # [ + # [ 0] 1, + # [ 1] 2, + # [ 2] 3, + # [ 3] .. [96], + # [97] 98, + # [98] 99, + # [99] 100 + # ] + #------------------------------------------------------------------------------ + def should_be_limited? + options[:limit] or (options[:limit].is_a?(Integer) and options[:limit] > 0) + end + + def get_limit_size + case options[:limit] + when true + DEFAULT_LIMIT_SIZE + else + options[:limit] + end + end + + def limited(data, width, is_hash = false) + limit = get_limit_size + if data.length <= limit + data + else + # Calculate how many elements to be displayed above and below the separator. + head = limit / 2 + tail = head - (limit - 1) % 2 + + # Add the proper elements to the temp array and format the separator. + temp = data[0, head] + [nil] + data[-tail, tail] + + temp[head] = if is_hash + "#{indent}#{data[head].strip} .. #{data[data.length - tail - 1].strip}" + else + "#{indent}[#{head.to_s.rjust(width)}] .. [#{data.length - tail - 1}]" + end + + temp + end + end + + + end +end diff --git a/lib/awesome_print/registrar.rb b/lib/awesome_print/registrar.rb new file mode 100644 index 0000000..a63475e --- /dev/null +++ b/lib/awesome_print/registrar.rb @@ -0,0 +1,20 @@ +module AwesomePrint + module Registrar + + def self.included(base) + base.send(:extend, ClassMethods) + end + + module ClassMethods + + attr_accessor :formatted_object_type + + def formatter_for(type) + self.formatted_object_type = type + + AwesomePrint::Formatter.register(self) + end + end + + end +end diff --git a/spec/ext/ostruct_spec.rb b/spec/ext/ostruct_spec.rb index 55a4d33..27884ac 100644 --- a/spec/ext/ostruct_spec.rb +++ b/spec/ext/ostruct_spec.rb @@ -1,4 +1,5 @@ require 'spec_helper' +require 'ostruct' RSpec.describe 'AwesomePrint Ostruct extension' do before do diff --git a/spec/formats_spec.rb b/spec/formats_spec.rb index 9427b44..2f755e9 100644 --- a/spec/formats_spec.rb +++ b/spec/formats_spec.rb @@ -119,7 +119,7 @@ EOS EOS end - it 'colored single line' do + it 'colored single line', focus: true do expect(@arr.ai(multiline: false)).to eq("[ \e[1;34m1\e[0m, \e[0;36m:two\e[0m, \e[0;33m\"three\"\e[0m, [ \e[1;31mnil\e[0m, [ \e[1;32mtrue\e[0m, \e[1;31mfalse\e[0m ] ] ]") end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d2ef52b..a31568f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -25,6 +25,8 @@ Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each do |file| require file end +require 'byebug' + ExtVerifier.require_dependencies!( %w( rails