# frozen_string_literal: trueRSpec::Support.require_rspec_support'encoded_string'RSpec::Support.require_rspec_support'hunk_generator'RSpec::Support.require_rspec_support"object_formatter"require'pp'moduleRSpecmoduleSupport# rubocop:disable Metrics/ClassLengthclassDifferdefdiff(actual,expected)diff=""unlessactual.nil?||expected.nil?ifall_strings?(actual,expected)ifany_multiline_strings?(actual,expected)diff=diff_as_string(coerce_to_string(actual),coerce_to_string(expected))endelsifno_procs?(actual,expected)&&no_numbers?(actual,expected)diff=diff_as_object(actual,expected)endenddiff.to_send# rubocop:disable Metrics/MethodLengthdefdiff_as_string(actual,expected)encoding=EncodedString.pick_encoding(actual,expected)actual=EncodedString.new(actual,encoding)expected=EncodedString.new(expected,encoding)output=EncodedString.new("\n",encoding)hunks=build_hunks(actual,expected)hunks.each_cons(2)do|prev_hunk,current_hunk|beginifcurrent_hunk.overlaps?(prev_hunk)add_old_hunk_to_hunk(current_hunk,prev_hunk)elseadd_to_output(output,prev_hunk.diff(format_type).to_s)endensureadd_to_output(output,"\n")endendfinalize_output(output,hunks.last.diff(format_type).to_s)ifhunks.lastcolor_diffoutputrescueEncoding::CompatibilityErrorhandle_encoding_errors(actual,expected)end# rubocop:enable Metrics/MethodLengthdefdiff_as_object(actual,expected)actual_as_string=object_to_string(actual)expected_as_string=object_to_string(expected)diff_as_string(actual_as_string,expected_as_string)enddefcolor?@colorenddefinitialize(opts={})@color=opts.fetch(:color,false)@object_preparer=opts.fetch(:object_preparer,lambda{|string|string})endprivatedefno_procs?(*args)safely_flatten(args).none?{|a|Proc===a}enddefall_strings?(*args)safely_flatten(args).all?{|a|String===a}enddefany_multiline_strings?(*args)all_strings?(*args)&&safely_flatten(args).any?{|a|multiline?(a)}enddefno_numbers?(*args)safely_flatten(args).none?{|a|Numeric===a}enddefcoerce_to_string(string_or_array)returnstring_or_arrayunlessArray===string_or_arraydiffably_stringify(string_or_array).join("\n")enddefdiffably_stringify(array)array.mapdo|entry|ifArray===entryentry.inspectelseentry.to_s.gsub("\n","\\n").gsub("\r","\\r")endendendifString.method_defined?(:encoding)defmultiline?(string)string.include?("\n".encode(string.encoding))endelsedefmultiline?(string)string.include?("\n")endenddefbuild_hunks(actual,expected)HunkGenerator.new(actual,expected).hunksenddeffinalize_output(output,final_line)add_to_output(output,final_line)add_to_output(output,"\n")enddefadd_to_output(output,string)output<<stringenddefadd_old_hunk_to_hunk(hunk,oldhunk)hunk.merge(oldhunk)enddefsafely_flatten(array)array=array.flatten(1)until(array==array.flatten(1))arrayenddefformat_type:unifiedenddefcolor(text,color_code)"\e[#{color_code}m#{text}\e[0m"enddefred(text)color(text,31)enddefgreen(text)color(text,32)enddefblue(text)color(text,34)enddefnormal(text)color(text,0)enddefcolor_diff(diff)returndiffunlesscolor?diff.lines.mapdo|line|caseline[0].chrwhen"+"greenlinewhen"-"redlinewhen"@"line[1].chr=="@"?blue(line):normal(line)elsenormal(line)endend.joinenddefobject_to_string(object)object=@object_preparer.call(object)caseobjectwhenHashhash_to_string(object)whenArrayPP.pp(ObjectFormatter.prepare_for_inspection(object),"".dup)whenStringobject=~/\n/?object:object.inspectelsePP.pp(object,"".dup)endenddefhash_to_string(hash)formatted_hash=ObjectFormatter.prepare_for_inspection(hash)formatted_hash.keys.sort_by{|k|k.to_s}.mapdo|key|pp_key=PP.singleline_pp(key,"".dup)pp_value=PP.singleline_pp(formatted_hash[key],"".dup)"#{pp_key} => #{pp_value},"end.join("\n")enddefhandle_encoding_errors(actual,expected)ifactual.source_encoding!=expected.source_encoding"Could not produce a diff because the encoding of the actual string "\"(#{actual.source_encoding}) differs from the encoding of the expected "\"string (#{expected.source_encoding})"else"Could not produce a diff because of the encoding of the string "\"(#{expected.source_encoding})"endendend# rubocop:enable Metrics/ClassLengthendend