public
Last active

  • Download Gist
comparison.rb
Ruby
1 2 3 4 5 6 7 8 9 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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
class Comparison
@@window = 64
@@prelude = 12
 
def self.window
@@window
end
 
def self.window=(val)
@@window = val
end
 
def self.prelude
@@prelude
end
 
def self.prelude=(val)
@@prelude = val
end
 
def initialize(expected, actual)
@expected = expected
@actual = actual
end
 
def same?
@expected == @actual
end
 
def different_at
if (@expected.nil? || @actual.nil?)
0
else
i = 0
while (i < @expected.size && i < @actual.size)
if @expected[i] != @actual[i]
break
end
i += 1
end
return i
end
end
 
def message
"Strings differ at position #{different_at}:\n" +
"expected: #{chunk(@expected)}\n" +
" actual: #{chunk(@actual)}\n"
end
 
def chunk(s)
prefix, middle, suffix = "...", "", "..."
 
start = different_at - @@prelude
if start < 0
prefix = ""
start = 0
end
 
stop = start + @@window
if stop > s.size
suffix = ""
stop = s.size
end
 
[prefix, s[start...stop].inspect, suffix].join
end
end
 
if Object.const_defined?(:Spec)
module Spec
module Matchers
class OperatorMatcher
end
class PositiveOperatorMatcher < OperatorMatcher #:nodoc:
def __delegate_operator(actual, operator, expected)
if actual.__send__(operator, expected)
true
elsif expected.is_a?(String) && actual.is_a?(String) && (operator == '==')
fail_with_message Comparison.new(expected, actual).message
elsif ['==', '===', '=~'].include?(operator)
fail_with_message("expected: #{expected.inspect},\n got: #{actual.inspect} (using #{operator})")
else
fail_with_message("expected: #{operator} #{expected.inspect},\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
end
end
end
end
end
end
comparison_spec.rb
Ruby
1 2 3 4 5 6 7 8 9 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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
here = File.dirname(__FILE__); require File.expand_path("#{here}/../spec_helper")
 
describe Comparison do
before do
@old_window = Comparison.window
Comparison.window = 16
@old_prelude = Comparison.prelude
Comparison.prelude = 8
end
 
after do
Comparison.window = @old_window
end
 
describe '#same?' do
it "says identical empty strings are the same" do
comparison = Comparison.new("", "")
comparison.same?.should be_true
end
 
it "says identical non-empty strings are the same" do
comparison = Comparison.new("abc", "abc")
comparison.same?.should be_true
end
 
it "says two nils are the same" do
comparison = Comparison.new(nil, nil)
comparison.same?.should be_true
end
 
it "says a string is different from a different string" do
comparison = Comparison.new("abc", "xyz")
comparison.same?.should be_false
end
 
it "says a string is different from nil" do
comparison = Comparison.new("abc", nil)
comparison.same?.should be_false
end
 
it "says nil is different from a string" do
comparison = Comparison.new(nil, "abc")
comparison.same?.should be_false
end
end
 
describe '#different_at' do
describe "returns the location where two strings differ" do
it "at the beginning of the strings" do
Comparison.new("abc", "xyz").different_at.should == 0
end
 
it "at the middle of the strings" do
Comparison.new("abc", "ayz").different_at.should == 1
end
 
it "when the expected string is longer" do
Comparison.new("abcd", "abc").different_at.should == 3
end
 
it "when the actual string is longer" do
Comparison.new("abc", "abcd").different_at.should == 3
end
 
it "with nil as the expected string" do
Comparison.new(nil, "abc").different_at.should == 0
end
 
it "with nil as the actual string" do
Comparison.new("abc", nil).different_at.should == 0
end
 
end
end
 
describe '#message' do
it 'shows the whole of both strings when the difference is near the start' do
Comparison.new("abc", "xyz").message.should ==
"Strings differ at position 0:\n" +
"expected: \"abc\"\n" +
" actual: \"xyz\"\n"
end
 
it 'shows ellipses when the difference is in the middle of a long string' do
Comparison.new("abcdefghijklmnopqrstuvwxyz", "abcdefghijkl*nopqrstuvwxyz").message.should ==
"Strings differ at position 12:\n" +
"expected: ...\"efghijklmnopqrst\"...\n" +
" actual: ...\"efghijkl*nopqrst\"...\n"
end
 
it 'shows ellipses when the difference is near the beginning of a long string' do
Comparison.new("abcdefghijklmnopqrstuvwxyz", "a*cdefghijklmnopqrstuvwxyz").message.should ==
"Strings differ at position 1:\n" +
"expected: \"abcdefghijklmnop\"...\n" +
" actual: \"a*cdefghijklmnop\"...\n"
end
 
it 'shows ellipses when the difference is near the end of a long string' do
Comparison.new("abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvw*yz").message.should ==
"Strings differ at position 23:\n" +
"expected: ...\"pqrstuvwxyz\"\n" +
" actual: ...\"pqrstuvw*yz\"\n"
end
 
it 'allows user to override the window size' do
Comparison.window = 10
Comparison.new("abcdefghijklmnopqrstuvwxyz", "a*cdefghijklmnopqrstuvwxyz").message.should ==
"Strings differ at position 1:\n" +
"expected: \"abcdefghij\"...\n" +
" actual: \"a*cdefghij\"...\n"
end
 
it 'allows user to override the prelude size' do
Comparison.prelude = 2
Comparison.new("abcdefghijklmnopqrstuvwxyz", "abcdefghijkl*nopqrstuvwxyz").message.should ==
"Strings differ at position 12:\n" +
"expected: ...\"klmnopqrstuvwxyz\"...\n" +
" actual: ...\"kl*nopqrstuvwxyz\"...\n"
end
 
end
 
it "overrides RSpec's == matcher for strings" do
lambda do
"xyz".should == "abc"
end.should raise_error(Spec::Expectations::ExpectationNotMetError, Comparison.new("abc", "xyz").message)
end
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.