Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
--- rspec-expectations/lib/rspec/expectations/diff_presenter.rb 2014-03-23 23:31:14.214580118 -0700
+++ rspec-support/lib/rspec/support/diff_presenter.rb 2014-03-23 23:27:18.402592651 -0700
@@ -1,14 +1,26 @@
-require 'diff/lcs'
-require 'diff/lcs/hunk'
+require "rspec/support/encoded_string"
+require "rspec/support/differ"
require 'pp'
-RSpec::Support.require_rspec_expectations "encoded_string"
-RSpec::Support.require_rspec_expectations "differ"
module RSpec
- module Expectations
- # Produces a diff for the submitted objects.
- # @private
+ module Support
class DiffPresenter
+ def diff(actual, expected)
+ diff = ""
+
+ if actual && expected
+ if all_strings?(actual, expected)
+ if any_multiline_strings?(actual, expected)
+ diff = diff_as_string(coerce_to_string(actual), coerce_to_string(expected))
+ end
+ elsif no_procs?(actual, expected) && no_numbers?(actual, expected)
+ diff = diff_as_object(actual, expected)
+ end
+ end
+
+ diff
+ end
+
def diff_as_string(actual, expected)
@encoding = pick_encoding actual, expected
@@ -44,8 +56,57 @@
diff_as_string(actual_as_string, expected_as_string)
end
+ attr_reader :color
+ alias_method :color?, :color
+
+ def initialize(opts={})
+ @color = opts.fetch(:color, false)
+ @object_preparer = opts.fetch(:object_preparer, lambda { |string| string })
+ end
+
private
+ def no_procs?(*args)
+ args.flatten.none? { |a| Proc === a}
+ end
+
+ def all_strings?(*args)
+ args.flatten.all? { |a| String === a}
+ end
+
+ def any_multiline_strings?(*args)
+ all_strings?(*args) && args.flatten.any? { |a| multiline?(a) }
+ end
+
+ def no_numbers?(*args)
+ args.flatten.none? { |a| Numeric === a}
+ end
+
+ def coerce_to_string(string_or_array)
+ return string_or_array unless Array === string_or_array
+ diffably_stringify(string_or_array).join("\n")
+ end
+
+ def diffably_stringify(array)
+ array.map do |entry|
+ if Array === entry
+ entry.inspect
+ else
+ entry.to_s.gsub("\n", "\\n")
+ end
+ end
+ end
+
+ if String.method_defined?(:encoding)
+ def multiline?(string)
+ string.include?("\n".encode(string.encoding))
+ end
+ else
+ def multiline?(string)
+ string.include?("\n")
+ end
+ end
+
def hunks
@hunks ||= Differ.new(@actual, @expected).hunks
end
@@ -88,7 +149,7 @@
end
def color_diff(diff)
- return diff unless RSpec::Matchers.configuration.color?
+ return diff unless color?
diff.lines.map { |line|
case line[0].chr
@@ -105,7 +166,7 @@
end
def object_to_string(object)
- object = Matchers::Composable.surface_descriptions_in(object)
+ object = @object_preparer.call(object)
case object
when Hash
object.keys.sort_by { |k| k.to_s }.map do |key|
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.