diff options
author | Austin Ziegler <austin@surfeasy.com> | 2012-03-21 02:27:56 -0400 |
---|---|---|
committer | Austin Ziegler <austin@surfeasy.com> | 2012-03-21 02:36:24 -0400 |
commit | a341ac7ca261a73e37c21a7f034f5892ea7dcde4 (patch) | |
tree | 0c695c928eceb5752a554a9dd483d3e141af624d | |
parent | 86e4e1ba222cab4dddf13caa5c56925c9a6401dc (diff) | |
download | diff-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.rdoc | 12 | ||||
-rw-r--r-- | lib/diff/lcs.rb | 67 | ||||
-rw-r--r-- | spec/change_spec.rb | 75 | ||||
-rw-r--r-- | spec/diff_spec.rb | 8 | ||||
-rw-r--r-- | spec/issues_spec.rb | 23 | ||||
-rw-r--r-- | spec/lcs_spec.rb | 24 | ||||
-rw-r--r-- | spec/patch_spec.rb | 74 | ||||
-rw-r--r-- | spec/spec_helper.rb | 12 | ||||
-rw-r--r-- | spec/traverse_balanced_spec.rb | 26 | ||||
-rw-r--r-- | spec/traverse_sequences_spec.rb | 110 |
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 |