diff-lcs 1.4.4 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/Contributing.md +3 -0
  3. data/History.md +219 -107
  4. data/License.md +6 -4
  5. data/Manifest.txt +15 -1
  6. data/Rakefile +81 -25
  7. data/bin/htmldiff +4 -4
  8. data/lib/diff/lcs/array.rb +1 -1
  9. data/lib/diff/lcs/backports.rb +2 -2
  10. data/lib/diff/lcs/block.rb +4 -4
  11. data/lib/diff/lcs/callbacks.rb +9 -7
  12. data/lib/diff/lcs/change.rb +19 -19
  13. data/lib/diff/lcs/htmldiff.rb +24 -16
  14. data/lib/diff/lcs/hunk.rb +35 -30
  15. data/lib/diff/lcs/internals.rb +24 -20
  16. data/lib/diff/lcs/ldiff.rb +37 -35
  17. data/lib/diff/lcs.rb +77 -75
  18. data/lib/diff-lcs.rb +1 -1
  19. data/spec/change_spec.rb +50 -50
  20. data/spec/diff_spec.rb +14 -14
  21. data/spec/fixtures/ldiff/output.diff.chef +4 -0
  22. data/spec/fixtures/ldiff/output.diff.chef-c +15 -0
  23. data/spec/fixtures/ldiff/output.diff.chef-e +3 -0
  24. data/spec/fixtures/ldiff/output.diff.chef-f +3 -0
  25. data/spec/fixtures/ldiff/output.diff.chef-u +9 -0
  26. data/spec/fixtures/ldiff/output.diff.chef2 +7 -0
  27. data/spec/fixtures/ldiff/output.diff.chef2-c +20 -0
  28. data/spec/fixtures/ldiff/output.diff.chef2-d +7 -0
  29. data/spec/fixtures/ldiff/output.diff.chef2-e +7 -0
  30. data/spec/fixtures/ldiff/output.diff.chef2-f +7 -0
  31. data/spec/fixtures/ldiff/output.diff.chef2-u +16 -0
  32. data/spec/fixtures/new-chef +4 -0
  33. data/spec/fixtures/new-chef2 +17 -0
  34. data/spec/fixtures/old-chef +4 -0
  35. data/spec/fixtures/old-chef2 +14 -0
  36. data/spec/hunk_spec.rb +19 -19
  37. data/spec/issues_spec.rb +48 -42
  38. data/spec/lcs_spec.rb +11 -11
  39. data/spec/ldiff_spec.rb +13 -11
  40. data/spec/patch_spec.rb +84 -84
  41. data/spec/sdiff_spec.rb +111 -109
  42. data/spec/spec_helper.rb +77 -76
  43. data/spec/traverse_balanced_spec.rb +191 -189
  44. data/spec/traverse_sequences_spec.rb +31 -33
  45. metadata +50 -23
  46. data/autotest/discover.rb +0 -3
data/Rakefile CHANGED
@@ -1,63 +1,118 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rubygems'
4
- require 'rspec'
5
- require 'hoe'
3
+ require "rubygems"
4
+ require "rspec"
5
+ require "rspec/core/rake_task"
6
+ require "hoe"
7
+
8
+ # This is required until https://github.com/seattlerb/hoe/issues/112 is fixed
9
+ class Hoe
10
+ def with_config
11
+ config = Hoe::DEFAULT_CONFIG
12
+
13
+ rc = File.expand_path("~/.hoerc")
14
+ homeconfig = load_config(rc)
15
+ config = config.merge(homeconfig)
16
+
17
+ localconfig = load_config(File.expand_path(File.join(Dir.pwd, ".hoerc")))
18
+ config = config.merge(localconfig)
19
+
20
+ yield config, rc
21
+ end
22
+
23
+ def load_config(name)
24
+ File.exist?(name) ? safe_load_yaml(name) : {}
25
+ end
26
+
27
+ def safe_load_yaml(name)
28
+ return safe_load_yaml_file(name) if YAML.respond_to?(:safe_load_file)
29
+
30
+ data = IO.binread(name)
31
+ YAML.safe_load(data, permitted_classes: [Regexp])
32
+ rescue
33
+ YAML.safe_load(data, [Regexp])
34
+ end
35
+
36
+ def safe_load_yaml_file(name)
37
+ YAML.safe_load_file(name, permitted_classes: [Regexp])
38
+ rescue
39
+ YAML.safe_load_file(name, [Regexp])
40
+ end
41
+ end
6
42
 
7
43
  Hoe.plugin :bundler
8
44
  Hoe.plugin :doofus
9
45
  Hoe.plugin :gemspec2
10
46
  Hoe.plugin :git
11
47
 
12
- if RUBY_VERSION < '1.9'
13
- class Array #:nodoc:
48
+ if RUBY_VERSION < "1.9"
49
+ class Array # :nodoc:
14
50
  def to_h
15
51
  Hash[*flatten(1)]
16
52
  end
17
53
  end
18
54
 
19
- class Gem::Specification #:nodoc:
20
- def metadata=(*); end
55
+ class Gem::Specification # :nodoc:
56
+ def metadata=(*)
57
+ end
21
58
 
22
- def default_value(*); end
59
+ def default_value(*)
60
+ end
23
61
  end
24
62
 
25
- class Object #:nodoc:
63
+ class Object # :nodoc:
26
64
  def caller_locations(*)
27
65
  []
28
66
  end
29
67
  end
30
68
  end
31
69
 
32
- _spec = Hoe.spec 'diff-lcs' do
33
- developer('Austin Ziegler', 'halostatue@gmail.com')
70
+ _spec = Hoe.spec "diff-lcs" do
71
+ developer("Austin Ziegler", "halostatue@gmail.com")
34
72
 
35
- require_ruby_version '>= 1.8'
73
+ require_ruby_version ">= 1.8"
36
74
 
37
- self.history_file = 'History.md'
38
- self.readme_file = 'README.rdoc'
39
- self.licenses = ['MIT', 'Artistic-2.0', 'GPL-2.0+']
75
+ self.history_file = "History.md"
76
+ self.readme_file = "README.rdoc"
77
+ self.licenses = ["MIT", "Artistic-2.0", "GPL-2.0-or-later"]
40
78
 
41
- extra_dev_deps << ['hoe-doofus', '~> 1.0']
42
- extra_dev_deps << ['hoe-gemspec2', '~> 1.1']
43
- extra_dev_deps << ['hoe-git', '~> 1.6']
44
- extra_dev_deps << ['hoe-rubygems', '~> 1.0']
45
- extra_dev_deps << ['rspec', '>= 2.0', '< 4']
46
- extra_dev_deps << ['rake', '>= 10.0', '< 14']
47
- extra_dev_deps << ['rdoc', '>= 0']
79
+ spec_extras[:metadata] = ->(val) { val["rubygems_mfa_required"] = "true" }
80
+
81
+ extra_dev_deps << ["hoe", ">= 3.0", "< 5"]
82
+ extra_dev_deps << ["hoe-doofus", "~> 1.0"]
83
+ extra_dev_deps << ["hoe-gemspec2", "~> 1.1"]
84
+ extra_dev_deps << ["hoe-git2", "~> 1.7"]
85
+ extra_dev_deps << ["hoe-rubygems", "~> 1.0"]
86
+ extra_dev_deps << ["rspec", ">= 2.0", "< 4"]
87
+ extra_dev_deps << ["rake", ">= 10.0", "< 14"]
88
+ extra_dev_deps << ["rdoc", ">= 6.3.1", "< 7"]
89
+ end
90
+
91
+ desc "Run all specifications"
92
+ RSpec::Core::RakeTask.new(:spec) do |t|
93
+ rspec_dirs = %w[spec lib].join(":")
94
+ t.rspec_opts = ["-I#{rspec_dirs}"]
48
95
  end
49
96
 
50
- if RUBY_VERSION >= '2.0' && RUBY_ENGINE == 'ruby'
97
+ Rake::Task["spec"].actions.uniq! { |a| a.source_location }
98
+
99
+ # standard:disable Style/HashSyntax
100
+ task :default => :spec unless Rake::Task["default"].prereqs.include?("spec")
101
+ task :test => :spec unless Rake::Task["test"].prereqs.include?("spec")
102
+ # standard:enable Style/HashSyntax
103
+
104
+ if RUBY_VERSION >= "2.0" && RUBY_ENGINE == "ruby"
51
105
  namespace :spec do
52
106
  desc "Runs test coverage. Only works Ruby 2.0+ and assumes 'simplecov' is installed."
53
107
  task :coverage do
54
- ENV['COVERAGE'] = 'yes'
55
- Rake::Task['spec'].execute
108
+ ENV["COVERAGE"] = "yes"
109
+ Rake::Task["spec"].execute
56
110
  end
57
111
  end
58
112
  end
59
113
 
60
114
  task :ruby18 do
115
+ # standard:disable Layout/HeredocIndentation
61
116
  puts <<-MESSAGE
62
117
  You are starting a barebones Ruby 1.8 docker environment. You will need to
63
118
  do the following:
@@ -70,5 +125,6 @@ do the following:
70
125
  Don't forget to restore your Gemfile.lock after testing.
71
126
 
72
127
  MESSAGE
128
+ # standard:enable Layout/HeredocIndentation
73
129
  sh "docker run -it --rm -v #{Dir.pwd}:/root/diff-lcs bellbind/docker-ruby18-rails2 bash -l"
74
130
  end
data/bin/htmldiff CHANGED
@@ -1,11 +1,11 @@
1
1
  #! /usr/bin/env ruby -w
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'diff/lcs'
5
- require 'diff/lcs/htmldiff'
4
+ require "diff/lcs"
5
+ require "diff/lcs/htmldiff"
6
6
 
7
7
  begin
8
- require 'text/format'
8
+ require "text/format"
9
9
  rescue LoadError
10
10
  Diff::LCS::HTMLDiff.can_expand_tabs = false
11
11
  end
@@ -24,7 +24,7 @@ options = { :title => "diff #{ARGV[0]} #{ARGV[1]}" }
24
24
  htmldiff = Diff::LCS::HTMLDiff.new(left, right, options)
25
25
 
26
26
  if ARGV[2]
27
- File.open(ARGV[2], 'w') do |f|
27
+ File.open(ARGV[2], "w") do |f|
28
28
  htmldiff.options[:output] = f
29
29
  htmldiff.run
30
30
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'diff/lcs'
3
+ require "diff/lcs"
4
4
 
5
5
  class Array
6
6
  include Diff::LCS
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  unless 0.respond_to?(:positive?)
4
- class Fixnum # rubocop:disable Lint/UnifiedInteger, Style/Documentation
4
+ class Fixnum # standard:disable Lint/UnifiedInteger
5
5
  def positive?
6
- self > 0 # rubocop:disable Style/NumericPredicate
6
+ self > 0
7
7
  end
8
8
  end
9
9
  end
@@ -25,13 +25,13 @@ class Diff::LCS::Block
25
25
  def op
26
26
  case [@remove.empty?, @insert.empty?]
27
27
  when [false, false]
28
- '!'
28
+ "!"
29
29
  when [false, true]
30
- '-'
30
+ "-"
31
31
  when [true, false]
32
- '+'
32
+ "+"
33
33
  else # [true, true]
34
- '^'
34
+ "^"
35
35
  end
36
36
  end
37
37
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'diff/lcs/change'
3
+ require "diff/lcs/change"
4
4
 
5
- module Diff::LCS # rubocop:disable Style/Documentation
5
+ module Diff::LCS
6
6
  # This callback object implements the default set of callback events,
7
7
  # which only returns the event itself. Note that #finished_a and
8
8
  # #finished_b are not implemented -- I haven't yet figured out where they
@@ -50,7 +50,9 @@ module Diff::LCS # rubocop:disable Style/Documentation
50
50
  BalancedCallbacks = DefaultCallbacks
51
51
 
52
52
  def self.callbacks_for(callbacks)
53
- callbacks.new rescue callbacks
53
+ callbacks.new
54
+ rescue
55
+ callbacks
54
56
  end
55
57
  end
56
58
 
@@ -107,7 +109,7 @@ class Diff::LCS::DiffCallbacks
107
109
  # Returns the difference set collected during the diff process.
108
110
  attr_reader :diffs
109
111
 
110
- def initialize # :yields self:
112
+ def initialize # :yields: self
111
113
  @hunk = []
112
114
  @diffs = []
113
115
 
@@ -131,11 +133,11 @@ class Diff::LCS::DiffCallbacks
131
133
  end
132
134
 
133
135
  def discard_a(event)
134
- @hunk << Diff::LCS::Change.new('-', event.old_position, event.old_element)
136
+ @hunk << Diff::LCS::Change.new("-", event.old_position, event.old_element)
135
137
  end
136
138
 
137
139
  def discard_b(event)
138
- @hunk << Diff::LCS::Change.new('+', event.new_position, event.new_element)
140
+ @hunk << Diff::LCS::Change.new("+", event.new_position, event.new_element)
139
141
  end
140
142
 
141
143
  def finish_hunk
@@ -302,7 +304,7 @@ class Diff::LCS::SDiffCallbacks
302
304
  # Returns the difference set collected during the diff process.
303
305
  attr_reader :diffs
304
306
 
305
- def initialize #:yields self:
307
+ def initialize # :yields: self
306
308
  @diffs = []
307
309
  yield self if block_given?
308
310
  end
@@ -10,7 +10,7 @@ class Diff::LCS::Change
10
10
  # (no change), '!' (changed), '<' (tail changes from first sequence), or
11
11
  # '>' (tail changes from second sequence). The last two ('<>') are only
12
12
  # found with Diff::LCS::diff and Diff::LCS::sdiff.
13
- VALID_ACTIONS = %w(+ - = ! > <).freeze
13
+ VALID_ACTIONS = %w[+ - = ! > <].freeze
14
14
 
15
15
  def self.valid_action?(action)
16
16
  VALID_ACTIONS.include? action
@@ -28,7 +28,7 @@ class Diff::LCS::Change
28
28
  @action, @position, @element = *args
29
29
 
30
30
  fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action)
31
- fail 'Invalid Position Type' unless @position.kind_of? IntClass
31
+ fail "Invalid Position Type" unless @position.is_a? IntClass
32
32
  end
33
33
 
34
34
  def inspect(*_args)
@@ -39,7 +39,7 @@ class Diff::LCS::Change
39
39
  [@action, @position, @element]
40
40
  end
41
41
 
42
- alias to_ary to_a
42
+ alias_method :to_ary, :to_a
43
43
 
44
44
  def self.from_a(arr)
45
45
  arr = arr.flatten(1)
@@ -49,7 +49,7 @@ class Diff::LCS::Change
49
49
  when 3
50
50
  Diff::LCS::Change.new(*(arr[0...3]))
51
51
  else
52
- fail 'Invalid change array format provided.'
52
+ fail "Invalid change array format provided."
53
53
  end
54
54
  end
55
55
 
@@ -70,27 +70,27 @@ class Diff::LCS::Change
70
70
  end
71
71
 
72
72
  def adding?
73
- @action == '+'
73
+ @action == "+"
74
74
  end
75
75
 
76
76
  def deleting?
77
- @action == '-'
77
+ @action == "-"
78
78
  end
79
79
 
80
80
  def unchanged?
81
- @action == '='
81
+ @action == "="
82
82
  end
83
83
 
84
84
  def changed?
85
- @action == '!'
85
+ @action == "!"
86
86
  end
87
87
 
88
88
  def finished_a?
89
- @action == '>'
89
+ @action == ">"
90
90
  end
91
91
 
92
92
  def finished_b?
93
- @action == '<'
93
+ @action == "<"
94
94
  end
95
95
  end
96
96
 
@@ -115,8 +115,8 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
115
115
  @action, @old_position, @old_element, @new_position, @new_element = *args
116
116
 
117
117
  fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action)
118
- fail 'Invalid (Old) Position Type' unless @old_position.nil? or @old_position.kind_of? IntClass
119
- fail 'Invalid (New) Position Type' unless @new_position.nil? or @new_position.kind_of? IntClass
118
+ fail "Invalid (Old) Position Type" unless @old_position.nil? || @old_position.is_a?(IntClass)
119
+ fail "Invalid (New) Position Type" unless @new_position.nil? || @new_position.is_a?(IntClass)
120
120
  end
121
121
 
122
122
  def to_a
@@ -127,7 +127,7 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
127
127
  ]
128
128
  end
129
129
 
130
- alias to_ary to_a
130
+ alias_method :to_ary, :to_a
131
131
 
132
132
  def self.from_a(arr)
133
133
  Diff::LCS::Change.from_a(arr)
@@ -139,15 +139,15 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
139
139
  ea = event.to_a
140
140
 
141
141
  case ea[0]
142
- when '-'
142
+ when "-"
143
143
  ea[2][1] = nil
144
- when '<'
145
- ea[0] = '-'
144
+ when "<"
145
+ ea[0] = "-"
146
146
  ea[2][1] = nil
147
- when '+'
147
+ when "+"
148
148
  ea[1][1] = nil
149
- when '>'
150
- ea[0] = '+'
149
+ when ">"
150
+ ea[0] = "+"
151
151
  ea[1][1] = nil
152
152
  end
153
153
 
@@ -1,15 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cgi'
3
+ require "cgi"
4
4
 
5
5
  # Produce a simple HTML diff view.
6
6
  class Diff::LCS::HTMLDiff
7
7
  class << self
8
- attr_accessor :can_expand_tabs #:nodoc:
8
+ attr_accessor :can_expand_tabs # :nodoc:
9
9
  end
10
10
  self.can_expand_tabs = true
11
11
 
12
- class Callbacks #:nodoc:
12
+ class Callbacks # :nodoc:
13
13
  attr_accessor :output
14
14
  attr_accessor :match_class
15
15
  attr_accessor :only_a_class
@@ -19,14 +19,14 @@ class Diff::LCS::HTMLDiff
19
19
  @output = output
20
20
  options ||= {}
21
21
 
22
- @match_class = options[:match_class] || 'match'
23
- @only_a_class = options[:only_a_class] || 'only_a'
24
- @only_b_class = options[:only_b_class] || 'only_b'
22
+ @match_class = options[:match_class] || "match"
23
+ @only_a_class = options[:only_a_class] || "only_a"
24
+ @only_b_class = options[:only_b_class] || "only_b"
25
25
  end
26
26
 
27
27
  def htmlize(element, css_class)
28
- element = '&nbsp;' if element.empty?
29
- %Q(<pre class="#{__send__(css_class)}">#{element}</pre>\n)
28
+ element = "&nbsp;" if element.empty?
29
+ %(<pre class="#{__send__(css_class)}">#{element}</pre>\n)
30
30
  end
31
31
  private :htmlize
32
32
 
@@ -46,13 +46,16 @@ class Diff::LCS::HTMLDiff
46
46
  end
47
47
  end
48
48
 
49
+ # standard:disable Style/HashSyntax
49
50
  DEFAULT_OPTIONS = {
50
51
  :expand_tabs => nil,
51
52
  :output => nil,
52
53
  :css => nil,
53
54
  :title => nil
54
55
  }.freeze
56
+ # standard:enable Style/HashSyntax
55
57
 
58
+ # standard:disable Layout/HeredocIndentation
56
59
  DEFAULT_CSS = <<-CSS
57
60
  body { margin: 0; }
58
61
  .diff
@@ -86,11 +89,12 @@ pre
86
89
  }
87
90
  h1 { margin-left: 2em; }
88
91
  CSS
92
+ # standard:enable Layout/HeredocIndentation
89
93
 
90
94
  def initialize(left, right, options = nil)
91
- @left = left
92
- @right = right
93
- @options = options
95
+ @left = left
96
+ @right = right
97
+ @options = options
94
98
 
95
99
  @options = DEFAULT_OPTIONS.dup if @options.nil?
96
100
  end
@@ -103,7 +107,7 @@ h1 { margin-left: 2em; }
103
107
 
104
108
  @options[:css] ||= DEFAULT_CSS.dup
105
109
 
106
- @options[:title] ||= 'diff'
110
+ @options[:title] ||= "diff"
107
111
  end
108
112
  private :verify_options
109
113
 
@@ -116,13 +120,14 @@ h1 { margin-left: 2em; }
116
120
  formatter = Text::Format.new
117
121
  formatter.tabstop = @options[:expand_tabs]
118
122
 
119
- @left.map! do |line| formatter.expand(line.chomp) end
120
- @right.map! do |line| formatter.expand(line.chomp) end
123
+ @left.map! { |line| formatter.expand(line.chomp) }
124
+ @right.map! { |line| formatter.expand(line.chomp) }
121
125
  end
122
126
 
123
- @left.map! do |line| CGI.escapeHTML(line.chomp) end
124
- @right.map! do |line| CGI.escapeHTML(line.chomp) end
127
+ @left.map! { |line| CGI.escapeHTML(line.chomp) }
128
+ @right.map! { |line| CGI.escapeHTML(line.chomp) }
125
129
 
130
+ # standard:disable Layout/HeredocIndentation
126
131
  @options[:output] << <<-OUTPUT
127
132
  <html>
128
133
  <head>
@@ -137,14 +142,17 @@ h1 { margin-left: 2em; }
137
142
  <span class="only_b">Only in New</span></p>
138
143
  <div class="diff">
139
144
  OUTPUT
145
+ # standard:enable Layout/HeredocIndentation
140
146
 
141
147
  callbacks = Callbacks.new(@options[:output])
142
148
  Diff::LCS.traverse_sequences(@left, @right, callbacks)
143
149
 
150
+ # standard:disable Layout/HeredocIndentation
144
151
  @options[:output] << <<-OUTPUT
145
152
  </div>
146
153
  </body>
147
154
  </html>
148
155
  OUTPUT
156
+ # standard:enable Layout/HeredocIndentation
149
157
  end
150
158
  end