Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/print struct like objects #226

Merged
merged 4 commits into from
May 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
- Improves spec performance and simplicity (Mauro George)
- Handle objects that have a custom #to_hash method (Elliot Shank)
- Fixes development dependencies for environments without rake (Edgar Cabrera #222 & Timothée Peignier #216)
- Creates #awesome_object_data to encapsulate the logic of printing objects'
internals so Structs and Objects can be printed as one (Waldyr de Souza)

1.6.1
- Fixes specs on all rails dependencies (Mauro George)
Expand Down
29 changes: 19 additions & 10 deletions lib/awesome_print/formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ def colorize(str, type)

private

# Check whether a variable_name is a method or ivar
#------------------------------------------------------------------------------
def valid_instance_var?(variable_name)
variable_name.to_s.start_with?('@')
end

# Catch all method to format an arbitrary object.
#------------------------------------------------------------------------------
def awesome_self(object, type)
Expand Down Expand Up @@ -127,7 +133,11 @@ def awesome_hash(h)
# Format an object.
#------------------------------------------------------------------------------
def awesome_object(o)
vars = o.instance_variables.map do |var|
awesome_object_data(o, o.instance_variables)
end

def awesome_object_data(o, 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 o.respond_to?(:"#{property}=")
o.respond_to?(property) ? :accessor : :writer
Expand All @@ -154,7 +164,13 @@ def awesome_object(o)
end
end
indented do
key << colorize(" = ", :hash) + @inspector.awesome(o.instance_variable_get(var))
var_contents = if valid_instance_var?(var)
o.instance_variable_get(var)
else
o.send(var) # Enables handling of Struct attributes
end

key << colorize(" = ", :hash) + @inspector.awesome(var_contents)
end
Copy link
Contributor

@gerrywastaken gerrywastaken May 11, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you feel about the following:

  • Changing the if condition to a call, to make it a bit more descriptive and pulling the logic outside of this method?
  • We could also write result += @inspector.awesome( after the branching to save writing it twice.
  • Adding a comment to the send line to explain it's inclusion.

e.g.

private

def valid_instance_var?(variable_name)
  variable_name.to_s.start_with?('@')
end

# [...]

  indented do
    var_contents = if valid_instance_var?(var)
      o.instance_variable_get(var)
    else
      o.send(var) # Enables handling of Struct attributes
    end

    key << colorize(" = ", :hash) + @inspector.awesome(var_contents)
  end

Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's way better than before. Tonight I'll patch it up.

end
if @options[:multiline]
Expand All @@ -173,14 +189,7 @@ def awesome_set(s)
# Format a Struct.
#------------------------------------------------------------------------------
def awesome_struct(s)
#
# The code is slightly uglier because of Ruby 1.8.6 quirks:
# awesome_hash(Hash[s.members.zip(s.values)]) <-- ArgumentError: odd number of arguments for Hash)
# awesome_hash(Hash[*s.members.zip(s.values).flatten]) <-- s.members returns strings, not symbols.
#
hash = {}
s.each_pair { |key, value| hash[key] = value }
awesome_hash(hash)
awesome_object_data(s, s.members)
end

# Format Class object.
Expand Down
48 changes: 18 additions & 30 deletions spec/formats_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -576,56 +576,44 @@

it "plain multiline" do
s1 = <<-EOS.strip
{
:address => "1313 Mockingbird Lane",
:name => "Herman Munster"
}
address = \"1313 Mockingbird Lane\",
name = \"Herman Munster\"
EOS
s2 = <<-EOS.strip
{
:name => "Herman Munster",
:address => "1313 Mockingbird Lane"
}
name = \"Herman Munster\",
address = \"1313 Mockingbird Lane\"
EOS
expect(@struct.ai(:plain => true)).to satisfy { |match| match == s1 || match == s2 }
expect(@struct.ai(:plain => true)).to satisfy { |out| out.match(s1) || out.match(s2) }
end

it "plain multiline indented" do
s1 = <<-EOS.strip
{
:address => "1313 Mockingbird Lane",
:name => "Herman Munster"
}
address = "1313 Mockingbird Lane",
name = "Herman Munster"
EOS
s2 = <<-EOS.strip
{
:name => "Herman Munster",
:address => "1313 Mockingbird Lane"
}
name = "Herman Munster",
address = "1313 Mockingbird Lane"
EOS
expect(@struct.ai(:plain => true, :indent => 1)).to satisfy { |match| match == s1 || match == s2 }
expect(@struct.ai(:plain => true, :indent => 1)).to satisfy { |out| out.match(s1) || out.match(s2) }
end

it "plain single line" do
s1 = "{ :address => \"1313 Mockingbird Lane\", :name => \"Herman Munster\" }"
s2 = "{ :name => \"Herman Munster\", :address => \"1313 Mockingbird Lane\" }"
expect(@struct.ai(:plain => true, :multiline => false)).to satisfy { |match| match == s1 || match == s2 }
s1 = "address = \"1313 Mockingbird Lane\", name = \"Herman Munster\""
s2 = "name = \"Herman Munster\", address = \"1313 Mockingbird Lane\""
expect(@struct.ai(:plain => true, :multiline => false)).to satisfy { |out| out.match(s1) || out.match(s2) }
end

it "colored multiline (default)" do
s1 = <<-EOS.strip
{
:address\e[0;37m => \e[0m\e[0;33m\"1313 Mockingbird Lane\"\e[0m,
:name\e[0;37m => \e[0m\e[0;33m\"Herman Munster\"\e[0m
}
address\e[0;37m = \e[0m\e[0;33m\"1313 Mockingbird Lane\"\e[0m,
name\e[0;37m = \e[0m\e[0;33m\"Herman Munster\"\e[0m
EOS
s2 = <<-EOS.strip
{
:name\e[0;37m => \e[0m\e[0;33m\"Herman Munster\"\e[0m,
:address\e[0;37m => \e[0m\e[0;33m\"1313 Mockingbird Lane\"\e[0m
}
name\e[0;37m = \e[0m\e[0;33m\"Herman Munster\"\e[0m,
address\e[0;37m = \e[0m\e[0;33m\"1313 Mockingbird Lane\"\e[0m
EOS
expect(@struct.ai).to satisfy { |match| match == s1 || match == s2 }
expect(@struct.ai).to satisfy { |out| out.include?(s1) || out.include?(s2) }
end
end

Expand Down