summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Ziegler <austin@surfeasy.com>2012-03-21 02:27:56 -0400
committerAustin Ziegler <austin@surfeasy.com>2012-03-21 02:36:24 -0400
commita341ac7ca261a73e37c21a7f034f5892ea7dcde4 (patch)
tree0c695c928eceb5752a554a9dd483d3e141af624d
parent86e4e1ba222cab4dddf13caa5c56925c9a6401dc (diff)
downloaddiff-lcs-a341ac7ca261a73e37c21a7f034f5892ea7dcde4.tar.gz
Major investigation to Diff::LCS bugs.
- Fixed some formatting and style issues. - Trailing spaces - Calling class methods using '.' instead of '::'. - Resolved Issue #2 by handling string[string.size, 1] properly (it returns "" not nil). - Added special case handling for Diff::LCS.patch so that it handles patches that are empty or contain no changes. - Adding temporary code to help determined the reason for the misidentification of patch direction. - Added a number of different specs to check for comparing the same value. - Added broken spec filtering.
-rw-r--r--History.rdoc12
-rw-r--r--lib/diff/lcs.rb67
-rw-r--r--spec/change_spec.rb75
-rw-r--r--spec/diff_spec.rb8
-rw-r--r--spec/issues_spec.rb23
-rw-r--r--spec/lcs_spec.rb24
-rw-r--r--spec/patch_spec.rb74
-rw-r--r--spec/spec_helper.rb12
-rw-r--r--spec/traverse_balanced_spec.rb26
-rw-r--r--spec/traverse_sequences_spec.rb110
10 files changed, 311 insertions, 120 deletions
diff --git a/History.rdoc b/History.rdoc
index ac8f7a3..a8946c9 100644
--- a/History.rdoc
+++ b/History.rdoc
@@ -1,3 +1,15 @@
+== ? / 2012-03-??
+* Major Enhancements:
+* Minor Enhancements:
+ * Added special case handling for Diff::LCS.patch so that it handles patches
+ that are empty or contain no changes.
+* Bug Fixes:
+ * Resolved Issue #2 by handling string[string.size, 1] properly (it returns
+ "" not nil).
+* Code Style Changes:
+ * Trailing spaces
+ * Calling class methods using '.' instead of '::'.
+
== 1.1.3 / 2011-08-27
* Converted to 'hoe' for release.
* Converted tests to RSpec 2.
diff --git a/lib/diff/lcs.rb b/lib/diff/lcs.rb
index 1013121..7218494 100644
--- a/lib/diff/lcs.rb
+++ b/lib/diff/lcs.rb
@@ -45,12 +45,12 @@ module Diff
# seq2 == seq1.patch!(sdiff)
# seq1 == seq2.unpatch(sdiff)
# seq1 == seq2.unpatch!(sdiff)
- #
+ #
# Default extensions are provided for Array and String objects through the
# use of 'diff/lcs/array' and 'diff/lcs/string'.
#
# == Introduction (by Mark-Jason Dominus)
- #
+ #
# <em>The following text is from the Perl documentation. The only changes
# have been to make the text appear better in Rdoc</em>.
#
@@ -71,7 +71,7 @@ module Diff
# new sequence *S* which can be obtained from the first sequence by
# deleting some items, and from the second sequence by deleting other
# items. You also want *S* to be as long as possible. In this case *S* is:
- #
+ #
# a b c d f g j z
#
# From there it's only a small step to get diff-like output:
@@ -91,7 +91,7 @@ module Diff
#
# A naive approach might start by matching up the +a+ and +b+ that appear
# at the beginning of each sequence, like this:
- #
+ #
# a x b y c z p d q
# a b c a b y c z
#
@@ -147,20 +147,20 @@ module Diff::LCS
# Returns the difference set between +self+ and +other+. See
# Diff::LCS#diff.
def diff(other, callbacks = nil, &block)
- Diff::LCS::diff(self, other, callbacks, &block)
+ Diff::LCS.diff(self, other, callbacks, &block)
end
# Returns the balanced ("side-by-side") difference set between +self+ and
# +other+. See Diff::LCS#sdiff.
def sdiff(other, callbacks = nil, &block)
- Diff::LCS::sdiff(self, other, callbacks, &block)
+ Diff::LCS.sdiff(self, other, callbacks, &block)
end
# Traverses the discovered longest common subsequences between +self+ and
# +other+. See Diff::LCS#traverse_sequences.
def traverse_sequences(other, callbacks = nil, &block)
traverse_sequences(self, other, callbacks ||
- Diff::LCS::YieldingCallbacks, &block)
+ Diff::LCS.YieldingCallbacks, &block)
end
# Traverses the discovered longest common subsequences between +self+ and
@@ -168,31 +168,31 @@ module Diff::LCS
# Diff::LCS#traverse_balanced.
def traverse_balanced(other, callbacks = nil, &block)
traverse_balanced(self, other, callbacks ||
- Diff::LCS::YieldingCallbacks, &block)
+ Diff::LCS.YieldingCallbacks, &block)
end
# Attempts to patch a copy of +self+ with the provided +patchset+. See
# Diff::LCS#patch.
def patch(patchset)
- Diff::LCS::patch(self.dup, patchset)
+ Diff::LCS.patch(self.dup, patchset)
end
# Attempts to unpatch a copy of +self+ with the provided +patchset+. See
# Diff::LCS#patch.
def unpatch(patchset)
- Diff::LCS::unpatch(self.dup, patchset)
+ Diff::LCS.unpatch(self.dup, patchset)
end
# Attempts to patch +self+ with the provided +patchset+. See
# Diff::LCS#patch!. Does no autodiscovery.
def patch!(patchset)
- Diff::LCS::patch!(self, patchset)
+ Diff::LCS.patch!(self, patchset)
end
# Attempts to unpatch +self+ with the provided +patchset+. See
# Diff::LCS#unpatch. Does no autodiscovery.
def unpatch!(patchset)
- Diff::LCS::unpatch!(self, patchset)
+ Diff::LCS.unpatch!(self, patchset)
end
end
@@ -230,7 +230,7 @@ module Diff::LCS
# Diff::LCS.diff computes the smallest set of additions and deletions
# necessary to turn the first sequence into the second, and returns a
# description of these changes.
- #
+ #
# See Diff::LCS::DiffCallbacks for the default behaviour. An alternate
# behaviour may be implemented with Diff::LCS::ContextDiffCallbacks. If
# a Class argument is provided for +callbacks+, #diff will attempt to
@@ -395,7 +395,7 @@ module Diff::LCS
bx = string ? seq2[bj, 1] : seq2[bj]
if b_line.nil?
- unless ax.nil?
+ unless ax.nil? or (string and ax.empty?)
event = Diff::LCS::ContextChange.new('-', ii, ax, bj, bx)
event = yield event if block_given?
callbacks.discard_a(event)
@@ -624,7 +624,7 @@ module Diff::LCS
end
end
- # Match
+ # Match
ax = string ? seq1[ai, 1] : seq1[ai]
bx = string ? seq2[bj, 1] : seq2[bj]
event = Diff::LCS::ContextChange.new('=', ai, ax, bj, bx)
@@ -680,16 +680,24 @@ module Diff::LCS
# version. If +direction+ is not specified (must be
# <tt>:patch</tt> or <tt>:unpatch</tt>), then discovery of the
# direction of the patch will be attempted.
+ #
+ # If the patchset is empty or all 'unchanged', the src value will be
+ # returned as either <tt>src.dup</tt> or <tt>src</tt>.
def patch(src, patchset, direction = nil)
+ patchset = __normalize_patchset(patchset)
+
+ if patchset.empty? or patchset.all? { |ps| ps.unchanged? }
+ return src.dup if src.respond_to? :dup
+ return src
+ end
+
string = src.kind_of?(String)
# Start with a new empty type of the source's class
res = src.class.new
# Normalize the patchset.
- patchset = __normalize_patchset(patchset)
- direction ||= Diff::LCS.__diff_direction(src, patchset)
- direction ||= :patch
+ direction ||= Diff::LCS.__diff_direction(src, patchset) || :patch
ai = bj = 0
@@ -791,7 +799,6 @@ module Diff::LCS
Diff::LCS.patch(src, patchset, :patch)
end
-# private
# Compute the longest common subsequence between the sequenced
# Enumerables +a+ and +b+. The result is an array whose contents is such
# that
@@ -934,7 +941,7 @@ module Diff::LCS
#
# Note: This will be deprecated as a public function in a future release.
def __diff_direction(src, patchset, limit = nil)
- count = left = left_miss = right = right_miss = 0
+ count = left_match = left_miss = right_match = right_miss = 0
string = src.kind_of?(String)
patchset.each do |change|
@@ -950,13 +957,13 @@ module Diff::LCS
case change.action
when '-'
if element == change.element
- left += 1
+ left_match += 1
else
left_miss += 1
end
when '+'
if element == change.element
- right += 1
+ right_match += 1
else
right_miss += 1
end
@@ -970,15 +977,16 @@ module Diff::LCS
case change.action
when '-' # Remove details from the old string
element = string ? src[change.old_position, 1] : src[change.old_position]
+
if element == change.old_element
- left += 1
+ left_match += 1
else
left_miss += 1
end
when '+'
element = string ? src[change.new_position, 1] : src[change.new_position]
if element == change.new_element
- right += 1
+ right_match += 1
else
right_miss += 1
end
@@ -991,11 +999,11 @@ module Diff::LCS
when '!'
element = string ? src[change.old_position, 1] : src[change.old_position]
if element == change.old_element
- left += 1
+ left_match += 1
else
element = string ? src[change.new_position, 1] : src[change.new_position]
if element == change.new_element
- right += 1
+ right_match += 1
else
left_miss += 1
right_miss += 1
@@ -1007,8 +1015,11 @@ module Diff::LCS
break if (not limit.nil?) && (count > limit)
end
- no_left = (left == 0) and (left_miss >= 0)
- no_right = (right == 0) and (right_miss >= 0)
+ if left_match.zero?
+ end
+
+ no_left = (left_match == 0) && (left_miss >= 0)
+ no_right = (right_match == 0) && (right_miss >= 0)
case [no_left, no_right]
when [false, true]
diff --git a/spec/change_spec.rb b/spec/change_spec.rb
index 9595732..152c306 100644
--- a/spec/change_spec.rb
+++ b/spec/change_spec.rb
@@ -3,68 +3,65 @@
require 'spec_helper'
describe Diff::LCS::Change do
-
describe "an add" do
subject { described_class.new('+', 0, 'element') }
- it { should_not be_deleting() }
- it { should be_adding() }
- it { should_not be_unchanged() }
- it { should_not be_changed() }
- it { should_not be_finished_a() }
- it { should_not be_finished_b() }
+ it { should_not be_deleting }
+ it { should be_adding }
+ it { should_not be_unchanged }
+ it { should_not be_changed }
+ it { should_not be_finished_a }
+ it { should_not be_finished_b }
end
describe "a delete" do
subject { described_class.new('-', 0, 'element') }
- it { should be_deleting() }
- it { should_not be_adding() }
- it { should_not be_unchanged() }
- it { should_not be_changed() }
- it { should_not be_finished_a() }
- it { should_not be_finished_b() }
+ it { should be_deleting }
+ it { should_not be_adding }
+ it { should_not be_unchanged }
+ it { should_not be_changed }
+ it { should_not be_finished_a }
+ it { should_not be_finished_b }
end
describe "an unchanged" do
subject { described_class.new('=', 0, 'element') }
- it { should_not be_deleting() }
- it { should_not be_adding() }
- it { should be_unchanged() }
- it { should_not be_changed() }
- it { should_not be_finished_a() }
- it { should_not be_finished_b() }
+ it { should_not be_deleting }
+ it { should_not be_adding }
+ it { should be_unchanged }
+ it { should_not be_changed }
+ it { should_not be_finished_a }
+ it { should_not be_finished_b }
end
describe "a changed" do
subject { described_class.new('!', 0, 'element') }
- it { should_not be_deleting() }
- it { should_not be_adding() }
- it { should_not be_unchanged() }
- it { should be_changed() }
- it { should_not be_finished_a() }
- it { should_not be_finished_b() }
+ it { should_not be_deleting }
+ it { should_not be_adding }
+ it { should_not be_unchanged }
+ it { should be_changed }
+ it { should_not be_finished_a }
+ it { should_not be_finished_b }
end
describe "a finished_a" do
subject { described_class.new('>', 0, 'element') }
- it { should_not be_deleting() }
- it { should_not be_adding() }
- it { should_not be_unchanged() }
- it { should_not be_changed() }
- it { should be_finished_a() }
- it { should_not be_finished_b() }
+ it { should_not be_deleting }
+ it { should_not be_adding }
+ it { should_not be_unchanged }
+ it { should_not be_changed }
+ it { should be_finished_a }
+ it { should_not be_finished_b }
end
describe "a finished_b" do
subject { described_class.new('<', 0, 'element') }
- it { should_not be_deleting() }
- it { should_not be_adding() }
- it { should_not be_unchanged() }
- it { should_not be_changed() }
- it { should_not be_finished_a() }
- it { should be_finished_b() }
+ it { should_not be_deleting }
+ it { should_not be_adding }
+ it { should_not be_unchanged }
+ it { should_not be_changed }
+ it { should_not be_finished_a }
+ it { should be_finished_b }
end
-
-
end
# vim: ft=ruby
diff --git a/spec/diff_spec.rb b/spec/diff_spec.rb
index d2c78a2..81f20bb 100644
--- a/spec/diff_spec.rb
+++ b/spec/diff_spec.rb
@@ -30,6 +30,14 @@ describe "Diff::LCS.diff" do
correct_diff.each { |hunk| hunk.each { |change| change[0] = '+' } }
change_diff(correct_diff).should == diff
end
+
+ it "should return an empty diff with (hello, hello)" do
+ Diff::LCS.diff(hello, hello).should == []
+ end
+
+ it "should return an empty diff with (hello_ary, hello_ary)" do
+ Diff::LCS.diff(hello_ary, hello_ary).should == []
+ end
end
# vim: ft=ruby
diff --git a/spec/issues_spec.rb b/spec/issues_spec.rb
new file mode 100644
index 0000000..32a81e6
--- /dev/null
+++ b/spec/issues_spec.rb
@@ -0,0 +1,23 @@
+# -*- ruby encoding: utf-8 -*-
+
+require 'spec_helper'
+
+describe "Diff::LCS Issues" do
+ include Diff::LCS::SpecHelper::Matchers
+
+ it "should not fail to provide a simple patchset (issue 1)", :broken => true do
+ s1, s2 = *%W(aX bXaX)
+ correct_forward_diff = [
+ [ [ '+', 0, 'b' ],
+ [ '+', 1, 'X' ] ],
+ ]
+
+ diff_s1_s2 = Diff::LCS.diff(s1, s2)
+ change_diff(correct_forward_diff).should == diff_s1_s2
+ expect do
+ Diff::LCS.patch(s1, diff_s1_s2).should == s2
+ end.to_not raise_error(RuntimeError, /provided patchset/)
+ end
+end
+
+# vim: ft=ruby
diff --git a/spec/lcs_spec.rb b/spec/lcs_spec.rb
index c95ba61..0fc077e 100644
--- a/spec/lcs_spec.rb
+++ b/spec/lcs_spec.rb
@@ -2,10 +2,10 @@
require 'spec_helper'
-describe "Diff::LCS.LCS and Diff::LCS.__lcs" do
+describe "Diff::LCS.__lcs" do
include Diff::LCS::SpecHelper::Matchers
- it "should return the correct raw values from Diff::LCS.__lcs" do
+ it "should return a meaningful LCS array with (seq1, seq2)" do
res = Diff::LCS.__lcs(seq1, seq2)
# The result of the LCS (less the +nil+ values) must be as long as the
# correct result.
@@ -20,6 +20,18 @@ describe "Diff::LCS.LCS and Diff::LCS.__lcs" do
x_seq2.should == correct_lcs
end
+ it "should return all indexes with (hello, hello)" do
+ Diff::LCS.__lcs(hello, hello).should == (0...hello.size).to_a
+ end
+
+ it "should return all indexes with (hello_ary, hello_ary)" do
+ Diff::LCS.__lcs(hello_ary, hello_ary).should == (0...hello_ary.size).to_a
+ end
+end
+
+describe "Diff::LCS.LCS" do
+ include Diff::LCS::SpecHelper::Matchers
+
it "should return the correct compacted values from Diff::LCS.LCS" do
res = Diff::LCS.LCS(seq1, seq2)
res.should == correct_lcs
@@ -31,6 +43,14 @@ describe "Diff::LCS.LCS and Diff::LCS.__lcs" do
res.should == correct_lcs
res.compact.should == res
end
+
+ it "should return %W(h e l l o) with (hello, hello)" do
+ Diff::LCS.LCS(hello, hello).should == hello.split(//)
+ end
+
+ it "should return hello_ary with (hello_ary, hello_ary)" do
+ Diff::LCS.LCS(hello_ary, hello_ary).should == hello_ary
+ end
end
# vim: ft=ruby
diff --git a/spec/patch_spec.rb b/spec/patch_spec.rb
index c3790ce..ad160c9 100644
--- a/spec/patch_spec.rb
+++ b/spec/patch_spec.rb
@@ -26,6 +26,16 @@ describe "Diff::LCS.patch" do
end
describe "using a Diff::LCS.diff patchset" do
+ describe "an empty patchset returns the source" do
+ it "works on a string (hello)" do
+ Diff::LCS::patch(hello, Diff::LCS.diff(hello, hello)).should == hello
+ end
+
+ it "works on an array %W(h e l l o)" do
+ Diff::LCS::patch(hello_ary, Diff::LCS.diff(hello_ary, hello_ary)).should == hello_ary
+ end
+ end
+
describe "with default diff callbacks (DiffCallbacks)" do
describe "forward (s1 -> s2)" do
it_has_behavior "patch sequences correctly" do
@@ -90,6 +100,16 @@ describe "Diff::LCS.patch" do
end
describe "using a Diff::LCS.sdiff patchset" do
+ describe "an empty patchset returns the source" do
+ it "works on a string (hello)" do
+ Diff::LCS::patch(hello, Diff::LCS.sdiff(hello, hello)).should == hello
+ end
+
+ it "works on an array %W(h e l l o)" do
+ Diff::LCS::patch(hello_ary, Diff::LCS.sdiff(hello_ary, hello_ary)).should == hello_ary
+ end
+ end
+
describe "with default diff callbacks (DiffCallbacks)" do
describe "forward (s1 -> s2)" do
it_has_behavior "patch sequences correctly" do
@@ -169,15 +189,16 @@ describe "Diff::LCS.patch" do
@patch_set_s2_s1 = Diff::LCS.diff(@s2, @s1)
end
- it "does not autodiscover s1 to s2 patches" do
- # It should, but it doesn't.
+ it "should autodiscover s1 to s2 patches", :broken => true do
expect do
Diff::LCS.patch(@s1, @patch_set_s1_s2).should == @s2
- end.to raise_error(RuntimeError, /provided patchset/)
+ end.to_not raise_error(RuntimeError, /provided patchset/)
+ end
+ it "should autodiscover s2 to s1 patches", :broken => true do
expect do
Diff::LCS.patch(@s1, @patch_set_s2_s1).should == @s2
- end.to raise_error(RuntimeError, /provided patchset/)
+ end.to_not raise_error(RuntimeError, /provided patchset/)
end
it "should autodiscover s2 to s1 the left-to-right patches" do
@@ -206,15 +227,16 @@ describe "Diff::LCS.patch" do
@patch_set_s2_s1 = Diff::LCS.diff(@s2, @s1, Diff::LCS::ContextDiffCallbacks)
end
- it "does not autodiscover s1 to s2 patches" do
- # It should, but it doesn't.
+ it "should autodiscover s1 to s2 patches", :broken => true do
expect do
Diff::LCS.patch(@s1, @patch_set_s1_s2).should == @s2
- end.to raise_error(RuntimeError, /provided patchset/)
+ end.to_not raise_error(RuntimeError, /provided patchset/)
+ end
+ it "should autodiscover s2 to s1 patches", :broken => true do
expect do
Diff::LCS.patch(@s1, @patch_set_s2_s1).should == @s2
- end.to raise_error(RuntimeError, /provided patchset/)
+ end.to_not raise_error(RuntimeError, /provided patchset/)
end
it "should autodiscover s2 to s1 the left-to-right patches" do
@@ -243,15 +265,16 @@ describe "Diff::LCS.patch" do
@patch_set_s2_s1 = Diff::LCS.diff(@s2, @s1, Diff::LCS::SDiffCallbacks)
end
- it "does not autodiscover s1 to s2 patches" do
- # It should, but it doesn't.
+ it "should autodiscover s1 to s2 patches", :broken => true do
expect do
Diff::LCS.patch(@s1, @patch_set_s1_s2).should == @s2
- end.to raise_error(RuntimeError, /provided patchset/)
+ end.to_not raise_error(RuntimeError, /provided patchset/)
+ end
+ it "should autodiscover s2 to s1 patches", :broken => true do
expect do
Diff::LCS.patch(@s1, @patch_set_s2_s1).should == @s2
- end.to raise_error(RuntimeError, /provided patchset/)
+ end.to_not raise_error(RuntimeError, /provided patchset/)
end
it "should autodiscover s2 to s1 the left-to-right patches" do
@@ -280,15 +303,16 @@ describe "Diff::LCS.patch" do
@patch_set_s2_s1 = Diff::LCS.sdiff(@s2, @s1)
end
- it "does not autodiscover s1 to s2 patches" do
- # It should, but it doesn't.
+ it "should autodiscover s1 to s2 patches", :broken => true do
expect do
Diff::LCS.patch(@s1, @patch_set_s1_s2).should == @s2
- end.to raise_error(RuntimeError, /provided patchset/)
+ end.to_not raise_error(RuntimeError, /provided patchset/)
+ end
+ it "should autodiscover s2 to s1 patches", :broken => true do
expect do
Diff::LCS.patch(@s1, @patch_set_s2_s1).should == @s2
- end.to raise_error(RuntimeError, /provided patchset/)
+ end.to_not raise_error(RuntimeError, /provided patchset/)
end
it "should autodiscover s2 to s1 the left-to-right patches" do
@@ -317,15 +341,16 @@ describe "Diff::LCS.patch" do
@patch_set_s2_s1 = Diff::LCS.sdiff(@s2, @s1, Diff::LCS::ContextDiffCallbacks)
end
- it "does not autodiscover s1 to s2 patches" do
- # It should, but it doesn't.
+ it "should autodiscover s1 to s2 patches", :broken => true do
expect do
Diff::LCS.patch(@s1, @patch_set_s1_s2).should == @s2
- end.to raise_error(RuntimeError, /provided patchset/)
+ end.to_not raise_error(RuntimeError, /provided patchset/)
+ end
+ it "should autodiscover s2 to s1 patches", :broken => true do
expect do
Diff::LCS.patch(@s1, @patch_set_s2_s1).should == @s2
- end.to raise_error(RuntimeError, /provided patchset/)
+ end.to_not raise_error(RuntimeError, /provided patchset/)
end
it "should autodiscover s2 to s1 the left-to-right patches" do
@@ -354,15 +379,16 @@ describe "Diff::LCS.patch" do
@patch_set_s2_s1 = Diff::LCS.sdiff(@s2, @s1, Diff::LCS::DiffCallbacks)
end
- it "does not autodiscover s1 to s2 patches" do
- # It should, but it doesn't.
+ it "should autodiscover s1 to s2 patches", :broken => true do
expect do
Diff::LCS.patch(@s1, @patch_set_s1_s2).should == @s2
- end.to raise_error(RuntimeError, /provided patchset/)
+ end.to_not raise_error(RuntimeError, /provided patchset/)
+ end
+ it "should autodiscover s2 to s1 patches", :broken => true do
expect do
Diff::LCS.patch(@s1, @patch_set_s2_s1).should == @s2
- end.to raise_error(RuntimeError, /provided patchset/)
+ end.to_not raise_error(RuntimeError, /provided patchset/)
end
it "should autodiscover s2 to s1 the left-to-right patches" do
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index bcd44de..10440fc 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -12,6 +12,14 @@ $:.unshift parent.join('lib')
require 'diff-lcs'
module Diff::LCS::SpecHelper
+ def hello
+ "hello"
+ end
+
+ def hello_ary
+ %W(h e l l o)
+ end
+
def seq1
%w(a b c e h j l m n p)
end
@@ -159,7 +167,6 @@ module Diff::LCS::SpecHelper
new_result
end
-
def simple_callback
callbacks = Object.new
class << callbacks
@@ -279,6 +286,9 @@ end
RSpec.configure do |conf|
conf.include Diff::LCS::SpecHelper
conf.alias_it_should_behave_like_to :it_has_behavior, 'has behavior:'
+ conf.filter_run_excluding :broken => true
+# conf.filter_run_including :broken => true
+# conf.filter_run_including :only => true
end
# vim: ft=ruby
diff --git a/spec/traverse_balanced_spec.rb b/spec/traverse_balanced_spec.rb
index 289676a..64b97f9 100644
--- a/spec/traverse_balanced_spec.rb
+++ b/spec/traverse_balanced_spec.rb
@@ -29,6 +29,32 @@ describe "Diff::LCS.traverse_balanced" do
end
end
+ describe "identical string sequences ('abc')" do
+ s1 = s2 = "abc"
+
+ result = [
+ [ '=', 0, 0 ],
+ [ '=', 1, 1 ],
+ [ '=', 2, 2 ]
+ ]
+
+ it_has_behavior "with a #change callback", s1, s2, result
+ it_has_behavior "without a #change callback", s1, s2, result
+ end
+
+ describe "identical array sequences %w(a b c)" do
+ s1 = s2 = %w(a b c)
+
+ result = [
+ [ '=', 0, 0 ],
+ [ '=', 1, 1 ],
+ [ '=', 2, 2 ]
+ ]
+
+ it_has_behavior "with a #change callback", s1, s2, result
+ it_has_behavior "without a #change callback", s1, s2, result
+ end
+
describe "sequences %w(a b c) & %w(a x c)" do
s1 = %w(a b c)
s2 = %w(a x c)
diff --git a/spec/traverse_sequences_spec.rb b/spec/traverse_sequences_spec.rb
index c7a5558..6f396dd 100644
--- a/spec/traverse_sequences_spec.rb
+++ b/spec/traverse_sequences_spec.rb
@@ -4,39 +4,97 @@ require 'spec_helper'
describe "Diff::LCS.traverse_sequences" do
describe "callback with no finishers" do
- before(:each) do
- @callback_s1_s2 = simple_callback_no_finishers
- Diff::LCS.traverse_sequences(seq1, seq2, @callback_s1_s2)
-
- @callback_s2_s1 = simple_callback_no_finishers
- Diff::LCS.traverse_sequences(seq2, seq1, @callback_s2_s1)
+ describe "over (seq1, seq2)" do
+ before(:each) do
+ @callback_s1_s2 = simple_callback_no_finishers
+ Diff::LCS.traverse_sequences(seq1, seq2, @callback_s1_s2)
+
+ @callback_s2_s1 = simple_callback_no_finishers
+ Diff::LCS.traverse_sequences(seq2, seq1, @callback_s2_s1)
+ end
+
+ it "should have the correct LCS result on left-matches" do
+ @callback_s1_s2.matched_a.should == correct_lcs
+ @callback_s2_s1.matched_a.should == correct_lcs
+ end
+
+ it "should have the correct LCS result on right-matches" do
+ @callback_s1_s2.matched_b.should == correct_lcs
+ @callback_s2_s1.matched_b.should == correct_lcs
+ end
+
+ it "should have the correct skipped sequences with the left sequence" do
+ @callback_s1_s2.discards_a.should == skipped_seq1
+ @callback_s2_s1.discards_a.should == skipped_seq2
+ end
+
+ it "should have the correct skipped sequences with the right sequence" do
+ @callback_s1_s2.discards_b.should == skipped_seq2
+ @callback_s2_s1.discards_b.should == skipped_seq1
+ end
+
+ it "should not have anything done markers from the left or right sequences" do
+ @callback_s1_s2.done_a.should be_empty
+ @callback_s1_s2.done_b.should be_empty
+ @callback_s2_s1.done_a.should be_empty
+ @callback_s2_s1.done_b.should be_empty
+ end
end
- it "should have the correct LCS result on left-matches" do
- @callback_s1_s2.matched_a.should == correct_lcs
- @callback_s2_s1.matched_a.should == correct_lcs
- end
+ describe "over (hello, hello)" do
+ before(:each) do
+ @callback = simple_callback_no_finishers
+ Diff::LCS.traverse_sequences(hello, hello, @callback)
+ end
- it "should have the correct LCS result on right-matches" do
- @callback_s1_s2.matched_b.should == correct_lcs
- @callback_s2_s1.matched_b.should == correct_lcs
- end
+ it "should have the correct LCS result on left-matches" do
+ @callback.matched_a.should == hello.split(//)
+ end
- it "should have the correct skipped sequences for the left sequence" do
- @callback_s1_s2.discards_a.should == skipped_seq1
- @callback_s2_s1.discards_a.should == skipped_seq2
- end
+ it "should have the correct LCS result on right-matches" do
+ @callback.matched_b.should == hello.split(//)
+ end
- it "should have the correct skipped sequences for the right sequence" do
- @callback_s1_s2.discards_b.should == skipped_seq2
- @callback_s2_s1.discards_b.should == skipped_seq1
+ it "should have the correct skipped sequences with the left sequence", :only => true do
+ @callback.discards_a.should be_empty
+ end
+
+ it "should have the correct skipped sequences with the right sequence" do
+ @callback.discards_b.should be_empty
+ end
+
+ it "should not have anything done markers from the left or right sequences" do
+ @callback.done_a.should be_empty
+ @callback.done_b.should be_empty
+ end
end
- it "should not have anything done markers from the left or right sequences" do
- @callback_s1_s2.done_a.should be_empty
- @callback_s1_s2.done_b.should be_empty
- @callback_s2_s1.done_a.should be_empty
- @callback_s2_s1.done_b.should be_empty
+ describe "over (hello_ary, hello_ary)" do
+ before(:each) do
+ @callback = simple_callback_no_finishers
+ Diff::LCS.traverse_sequences(hello_ary, hello_ary, @callback)
+ end
+
+ it "should have the correct LCS result on left-matches" do
+ @callback.matched_a.should == hello_ary
+ end
+
+ it "should have the correct LCS result on right-matches" do
+ @callback.matched_b.should == hello_ary
+ end
+
+ it "should have the correct skipped sequences with the left sequence" do
+ @callback.discards_a.should be_empty
+ end
+
+ it "should have the correct skipped sequences with the right sequence" do
+ @callback.discards_b.should be_empty
+ end
+
+ it "should not have anything done markers from the left or right sequences" do
+ @callback.done_a.should be_empty
+ @callback.done_b.should be_empty
+ end
end
end