Class: RSpec::Expectations::Differ

Inherits:
Object
  • Object
show all
Defined in:
lib/rspec/expectations/differ.rb

Instance Method Summary (collapse)

Instance Method Details

- (Object) diff_as_object(actual, expected)

58
59
60
61
62
63
64
# File 'lib/rspec/expectations/differ.rb', line 58
def diff_as_object(actual, expected)
  actual_as_string = object_to_string(actual)
  expected_as_string = object_to_string(expected)
  if diff = diff_as_string(actual_as_string, expected_as_string)
    color_diff diff
  end
end

- (Object) diff_as_string(input_data_new, input_data_old)

This is snagged from diff/lcs/ldiff.rb (which is a commandline tool)

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/rspec/expectations/differ.rb', line 10
def diff_as_string(input_data_new, input_data_old)
  encoding = pick_encoding input_data_new, input_data_old
  output = matching_encoding("", encoding)
  data_old = input_data_old.split(matching_encoding("\n", encoding)).map! { |e| e.chomp }
  data_new = input_data_new.split(matching_encoding("\n", encoding)).map! { |e| e.chomp }
  diffs = Diff::LCS.diff(data_old, data_new)
  return output if diffs.empty?
  oldhunk = hunk = nil
  file_length_difference = 0
  diffs.each do |piece|
    begin
      hunk = Diff::LCS::Hunk.new(
        data_old, data_new, piece, context_lines, file_length_difference
      )
      file_length_difference = hunk.file_length_difference
      next unless oldhunk
      # Hunks may overlap, which is why we need to be careful when our
      # diff includes lines of context. Otherwise, we might print
      # redundant lines.
      if (context_lines > 0) and hunk.overlaps?(oldhunk)
        if hunk.respond_to?(:merge)
          # diff-lcs 1.2.x
          hunk.merge(oldhunk)
        else
          # diff-lcs 1.1.3
          hunk.unshift(oldhunk)
        end
      else
        output << matching_encoding(oldhunk.diff(format).to_s, encoding)
      end
    ensure
      oldhunk = hunk
      output << matching_encoding("\n", encoding)
    end
  end
  #Handle the last remaining hunk
  output << matching_encoding(oldhunk.diff(format).to_s, encoding)
  output << matching_encoding("\n", encoding)
  color_diff output
rescue Encoding::CompatibilityError
  if input_data_new.encoding != input_data_old.encoding
    "Could not produce a diff because the encoding of the actual string (#{input_data_old.encoding}) "+
    "differs from the encoding of the expected string (#{input_data_new.encoding})"
  else
    "Could not produce a diff because of the encoding of the string (#{input_data_old.encoding})"
  end
end

- (Object) matching_encoding(string, encoding)

137
138
139
140
141
# File 'lib/rspec/expectations/differ.rb', line 137
def matching_encoding(string, encoding)
  string.encode encoding
rescue Encoding::UndefinedConversionError
  string.encode(encoding, :undef => :replace)
end

- (Object) pick_encoding(source_a, source_b)

133
134
135
# File 'lib/rspec/expectations/differ.rb', line 133
def pick_encoding(source_a, source_b)
  Encoding.compatible?(source_a, source_b) || Encoding.default_external
end