dirb 1.1.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +48 -19
- data/VERSION +1 -1
- data/dirb.gemspec +5 -2
- data/lib/dirb.rb +8 -92
- data/lib/dirb/diff.rb +105 -0
- data/lib/dirb/format.rb +33 -0
- data/lib/dirb/html_formatter.rb +90 -0
- data/spec/dirb_spec.rb +126 -4
- metadata +8 -5
data/README.md
CHANGED
@@ -6,9 +6,24 @@ way to generate a diff from two strings. Instead of reimplementing the LCS diff
|
|
6
6
|
algorithm Dirb uses battle tested Unix diff to generate diffs, and focuses on
|
7
7
|
providing a convenient interface, and getting out of your way.
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
Supported Formats
|
10
|
+
-----------------
|
11
|
+
|
12
|
+
It provides several built in format options which can be passed to
|
13
|
+
`Dirb::Diff#to_s`.
|
14
|
+
|
15
|
+
* `:text` - Plain text output
|
16
|
+
* `:color` - ANSI colorized text suitable for use in a terminal
|
17
|
+
* `:html` - HTML output. Since version 2.0 this format does inline
|
18
|
+
highlighting of the changes between two the changes within
|
19
|
+
lines.
|
20
|
+
* `:html_simple` - HTML output without inline highlighting. This may be
|
21
|
+
useful in situations where high performance is required or
|
22
|
+
simpler output is desired.
|
23
|
+
|
24
|
+
A default format can be set like so:
|
25
|
+
|
26
|
+
`Dirb::Diff.default_format = :html`
|
12
27
|
|
13
28
|
Getting Started
|
14
29
|
---------------
|
@@ -39,7 +54,7 @@ Here's an example of using Dirb to diff two strings
|
|
39
54
|
|
40
55
|
Outputing the diff as html is easy too.
|
41
56
|
|
42
|
-
>> puts Dirb::Diff.new(string1, string2).to_s(:
|
57
|
+
>> puts Dirb::Diff.new(string1, string2).to_s(:html_simple)
|
43
58
|
<div class="diff">
|
44
59
|
<ul>
|
45
60
|
<li class="del"><del>Hello how are you</del></li>
|
@@ -56,26 +71,22 @@ Then try adding this css to your stylesheets:
|
|
56
71
|
.diff ul{background:#fff;overflow:auto;font-size:13px;list-style:none;margin:0;padding:0;display:table;width:100%;}
|
57
72
|
.diff del, .diff ins{display:block;text-decoration:none;}
|
58
73
|
.diff li{padding:0; display:table-row;margin: 0;}
|
59
|
-
.diff li.ins{background:#9f9;}
|
60
|
-
.diff li.del{background:#ccf;}
|
61
|
-
.diff li:hover{background:#ffc}
|
62
74
|
.diff del, .diff ins, .diff span{white-space:pre;font-family:courier;}
|
75
|
+
.diff li.ins{background:#9f9;}
|
76
|
+
.diff li.del{background:#fcc;}
|
77
|
+
.diff li.ins strong{font-weight:normal; background: #6f6 }
|
78
|
+
.diff li.del strong{font-weight:normal; background: #f99 }
|
63
79
|
|
64
|
-
|
65
|
-
use ANSI termnial color escape sequences.
|
80
|
+
You can also diff files instead of strings
|
66
81
|
|
67
|
-
>> Dirb::Diff.
|
68
|
-
=> :color
|
69
|
-
>> puts Dirb::Diff.new(string1, string2) # prints color in the terminal
|
70
|
-
-Hello how are you
|
71
|
-
+Hello how are you?
|
72
|
-
I'm fine
|
73
|
-
-That's great
|
74
|
-
+That's swell
|
82
|
+
>> puts Dirb::Diff.new('/tmp/foo', '/tmp/bar', :source => 'files')
|
75
83
|
|
84
|
+
Custom Formats
|
85
|
+
--------------
|
76
86
|
|
77
|
-
|
78
|
-
enumberable interface which lets you iterate over
|
87
|
+
Dirb tries to make generating your own custom formatted output easy.
|
88
|
+
`Dirb::Diff` provides an enumberable interface which lets you iterate over
|
89
|
+
lines in the diff.
|
79
90
|
|
80
91
|
>> Dirb::Diff.new("foo\nbar\n", "foo\nbar\nbaz\n").each do |line|
|
81
92
|
>* case line
|
@@ -86,7 +97,25 @@ enumberable interface which lets you iterate over lines in the diff.
|
|
86
97
|
line +baz added
|
87
98
|
=> [" foo\n", " bar\n", "+baz\n"]
|
88
99
|
|
100
|
+
You can also use `Dirb::Diff#each_chunk` to iterate each grouping of additions,
|
101
|
+
deletions, and unchanged in a diff.
|
102
|
+
|
103
|
+
>> Dirb::Diff.new("foo\nbar\nbang\nbaz\n", "foo\nbar\nbing\nbong\n").each_chunk.to_a
|
104
|
+
=> [" foo\n bar\n", "-bang\n-baz\n", "+bing\n+bong\n"]
|
105
|
+
|
89
106
|
Use `#map`, `#inject`, or any of Enumerable's methods. Go crazy.
|
90
107
|
|
108
|
+
Ruby Version Compatibility
|
109
|
+
-------------------------
|
110
|
+
|
111
|
+
Support for Ruby 1.8.6 was dropped beggining at version 2.0 in order to support
|
112
|
+
the chainable enumerators available in 1.8.7 and 1.9.
|
113
|
+
|
114
|
+
If you want to use Dirb and Ruby 1.8.6 then:
|
115
|
+
|
116
|
+
$ gem install dirb -v1.1.0
|
117
|
+
|
118
|
+
---------------------------------------------------------------------
|
119
|
+
|
91
120
|
Report bugs or request features at http://github.com/samg/Dirb/issues
|
92
121
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.0.0
|
data/dirb.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{dirb}
|
8
|
-
s.version = "
|
8
|
+
s.version = "2.0.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Sam Goldstein"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-11-20}
|
13
13
|
s.description = %q{Convenient diffing in ruby}
|
14
14
|
s.email = %q{sgrock@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -25,6 +25,9 @@ Gem::Specification.new do |s|
|
|
25
25
|
"VERSION",
|
26
26
|
"dirb.gemspec",
|
27
27
|
"lib/dirb.rb",
|
28
|
+
"lib/dirb/diff.rb",
|
29
|
+
"lib/dirb/format.rb",
|
30
|
+
"lib/dirb/html_formatter.rb",
|
28
31
|
"spec/dirb_spec.rb"
|
29
32
|
]
|
30
33
|
s.homepage = %q{http://github.com/samg/dirb/tree/master}
|
data/lib/dirb.rb
CHANGED
@@ -1,96 +1,12 @@
|
|
1
|
-
require 'rubygems'
|
2
1
|
require 'tempfile'
|
3
2
|
require 'open3'
|
4
3
|
require 'erb'
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
attr_writer :default_format
|
9
|
-
def default_format
|
10
|
-
@default_format || :text
|
11
|
-
end
|
12
|
-
end
|
13
|
-
include Enumerable
|
14
|
-
attr_reader :string1, :string2, :diff_options, :diff
|
15
|
-
def initialize(string1, string2, diff_options = "-U 10000")
|
16
|
-
@string1, @string2 = string1, string2
|
17
|
-
@diff_options = diff_options
|
18
|
-
end
|
19
|
-
|
20
|
-
def diff
|
21
|
-
@diff ||= Open3.popen3(
|
22
|
-
*[diff_bin, diff_options, tempfile(string1), tempfile(string2)]
|
23
|
-
) { |i, o, e| o.read }
|
24
|
-
@diff = @string1.gsub(/^/, " ") if @diff =~ /\A\s*\Z/
|
25
|
-
@diff
|
26
|
-
end
|
27
|
-
|
28
|
-
def each &block
|
29
|
-
diff.split("\n").reject{|x| x =~ /^---|\+\+\+|@@/ }.each do |line|
|
30
|
-
block.call line + "\n"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def tempfile(string)
|
35
|
-
t = Tempfile.new('dirb')
|
36
|
-
t.print(string)
|
37
|
-
t.flush
|
38
|
-
t.path
|
39
|
-
end
|
40
|
-
|
41
|
-
def to_s(format = nil)
|
42
|
-
format ||= self.class.default_format
|
43
|
-
formats = Format.instance_methods(false).map{|x| x.to_s}
|
44
|
-
if formats.include? format.to_s
|
45
|
-
enum = self.to_a
|
46
|
-
enum.extend Format
|
47
|
-
enum.send format
|
48
|
-
else
|
49
|
-
raise ArgumentError,
|
50
|
-
"Format #{format.inspect} not found in #{formats.inspect}"
|
51
|
-
end
|
52
|
-
end
|
53
|
-
private
|
54
|
-
|
55
|
-
def diff_bin
|
56
|
-
bin = `which diff`.chomp
|
57
|
-
if bin.empty?
|
58
|
-
raise "Can't find a diff executable in PATH #{ENV['PATH']}"
|
59
|
-
end
|
60
|
-
bin
|
61
|
-
end
|
62
|
-
|
63
|
-
module Format
|
64
|
-
def color
|
65
|
-
map do |line|
|
66
|
-
case line
|
67
|
-
when /^\+/
|
68
|
-
"\033[32m#{line.chomp}\033[0m"
|
69
|
-
when /^-/
|
70
|
-
"\033[31m#{line.chomp}\033[0m"
|
71
|
-
else
|
72
|
-
line.chomp
|
73
|
-
end
|
74
|
-
end.join("\n") + "\n"
|
75
|
-
end
|
76
|
-
|
77
|
-
def text
|
78
|
-
to_a.join
|
79
|
-
end
|
80
|
-
|
81
|
-
def html
|
82
|
-
lines = map do |line|
|
83
|
-
case line
|
84
|
-
when /^\+/
|
85
|
-
' <li class="ins"><ins>' + ERB::Util.h(line.gsub(/^./, '').chomp) + '</ins></li>'
|
86
|
-
when /^-/
|
87
|
-
' <li class="del"><del>' + ERB::Util.h(line.gsub(/^./, '').chomp) + '</del></li>'
|
88
|
-
when /^ /
|
89
|
-
' <li class="unchanged"><span>' + ERB::Util.h(line.gsub(/^./, '').chomp) + '</span></li>'
|
90
|
-
end
|
91
|
-
end
|
92
|
-
%'<div class="diff">\n <ul>\n#{lines.join("\n")}\n </ul>\n</div>\n'
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
4
|
+
# 1.9 compatibility
|
5
|
+
if defined? Enumerator and ! defined? Enumerable::Enumerator
|
6
|
+
Enumerable::Enumerator = Enumerator
|
96
7
|
end
|
8
|
+
|
9
|
+
module Dirb; end
|
10
|
+
require File.join(File.dirname(__FILE__), 'dirb', 'format')
|
11
|
+
require File.join(File.dirname(__FILE__), 'dirb', 'html_formatter')
|
12
|
+
require File.join(File.dirname(__FILE__), 'dirb', 'diff')
|
data/lib/dirb/diff.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
module Dirb
|
2
|
+
class Diff
|
3
|
+
class << self
|
4
|
+
attr_writer :default_format
|
5
|
+
def default_format
|
6
|
+
@default_format || :text
|
7
|
+
end
|
8
|
+
end
|
9
|
+
include Enumerable
|
10
|
+
attr_reader :string1, :string2, :options, :diff
|
11
|
+
|
12
|
+
# supported options
|
13
|
+
# +:diff+:: A cli options string passed to diff
|
14
|
+
# +:source+:: Either _strings_ or _files_. Determines whether string1
|
15
|
+
# and string2 should be interpreted as strings or file paths.
|
16
|
+
def initialize(string1, string2, options = {})
|
17
|
+
@options = {:diff => '-U 10000', :source => 'strings'}.merge(options)
|
18
|
+
if ! ['strings', 'files'].include?(@options[:source])
|
19
|
+
raise ArgumentError, "Invalid :source option #{@options[:source].inspect}. Supported options are 'strings' and 'files'."
|
20
|
+
end
|
21
|
+
@string1, @string2 = string1, string2
|
22
|
+
end
|
23
|
+
|
24
|
+
def diff
|
25
|
+
@diff ||= begin
|
26
|
+
paths = case options[:source]
|
27
|
+
when 'strings'
|
28
|
+
[tempfile(string1), tempfile(string2)]
|
29
|
+
when 'files'
|
30
|
+
[string1, string2]
|
31
|
+
end
|
32
|
+
diff ||= Open3.popen3(
|
33
|
+
*[ diff_bin, options[:diff], *paths ]
|
34
|
+
) { |i, o, e| o.read }
|
35
|
+
if diff =~ /\A\s*\Z/
|
36
|
+
diff = case options[:source]
|
37
|
+
when 'strings' then string1
|
38
|
+
when 'files' then File.read(string1)
|
39
|
+
end.gsub(/^/, " ")
|
40
|
+
end
|
41
|
+
diff
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def each
|
46
|
+
lines = diff.split("\n").reject{|x| x =~ /^---|\+\+\+|@@|\\\\/ }.
|
47
|
+
map{|line| line + "\n"}
|
48
|
+
if block_given?
|
49
|
+
lines.each{|line| yield line}
|
50
|
+
else
|
51
|
+
Enumerable::Enumerator.new(lines)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def each_chunk
|
56
|
+
old_state = nil
|
57
|
+
chunks = inject([]) do |cc, line|
|
58
|
+
state = line.each_char.first
|
59
|
+
if state == old_state
|
60
|
+
cc.last << line
|
61
|
+
else
|
62
|
+
cc.push line.dup
|
63
|
+
end
|
64
|
+
old_state = state
|
65
|
+
cc
|
66
|
+
end
|
67
|
+
|
68
|
+
if block_given?
|
69
|
+
chunks.each{|chunk| yield chunk }
|
70
|
+
else
|
71
|
+
Enumerable::Enumerator.new(chunks)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def tempfile(string)
|
76
|
+
t = Tempfile.new('dirb')
|
77
|
+
t.print(string)
|
78
|
+
t.flush
|
79
|
+
t.path
|
80
|
+
end
|
81
|
+
|
82
|
+
def to_s(format = nil)
|
83
|
+
format ||= self.class.default_format
|
84
|
+
formats = Format.instance_methods(false).map{|x| x.to_s}
|
85
|
+
if formats.include? format.to_s
|
86
|
+
enum = self
|
87
|
+
enum.extend Format
|
88
|
+
enum.send format
|
89
|
+
else
|
90
|
+
raise ArgumentError,
|
91
|
+
"Format #{format.inspect} not found in #{formats.inspect}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
private
|
95
|
+
|
96
|
+
def diff_bin
|
97
|
+
bin = `which diff`.chomp
|
98
|
+
if bin.empty?
|
99
|
+
raise "Can't find a diff executable in PATH #{ENV['PATH']}"
|
100
|
+
end
|
101
|
+
bin
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
data/lib/dirb/format.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
module Dirb
|
2
|
+
module Format
|
3
|
+
# ANSI color output suitable for terminal output
|
4
|
+
def color
|
5
|
+
map do |line|
|
6
|
+
case line
|
7
|
+
when /^\+/
|
8
|
+
"\033[32m#{line.chomp}\033[0m"
|
9
|
+
when /^-/
|
10
|
+
"\033[31m#{line.chomp}\033[0m"
|
11
|
+
else
|
12
|
+
line.chomp
|
13
|
+
end
|
14
|
+
end.join("\n") + "\n"
|
15
|
+
end
|
16
|
+
|
17
|
+
# Basic text output
|
18
|
+
def text
|
19
|
+
to_a.join
|
20
|
+
end
|
21
|
+
|
22
|
+
# Basic html output which does not attempt to highlight the changes
|
23
|
+
# between lines, and is more performant.
|
24
|
+
def html_simple
|
25
|
+
HtmlFormatter.new(self).to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
# Html output which does inline highlighting of changes between two lines.
|
29
|
+
def html
|
30
|
+
HtmlFormatter.new(self, :highlight_words => true).to_s
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Dirb
|
2
|
+
class HtmlFormatter
|
3
|
+
def initialize(diff, options = {})
|
4
|
+
@diff = diff
|
5
|
+
@options = options
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
if @options[:highlight_words]
|
10
|
+
wrap_lines(highlighted_words)
|
11
|
+
else
|
12
|
+
wrap_lines(@diff.map{|line| wrap_line(ERB::Util.h(line))})
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def wrap_line(line)
|
18
|
+
cleaned = line.gsub(/^./, '').chomp
|
19
|
+
case line
|
20
|
+
when /^\+/
|
21
|
+
' <li class="ins"><ins>' + cleaned + '</ins></li>'
|
22
|
+
when /^-/
|
23
|
+
' <li class="del"><del>' + cleaned + '</del></li>'
|
24
|
+
when /^ /
|
25
|
+
' <li class="unchanged"><span>' + cleaned + '</span></li>'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def wrap_lines(lines)
|
30
|
+
%'<div class="diff">\n <ul>\n#{lines.join("\n")}\n </ul>\n</div>\n'
|
31
|
+
end
|
32
|
+
|
33
|
+
def highlighted_words
|
34
|
+
chunks = @diff.each_chunk.to_a
|
35
|
+
processed = []
|
36
|
+
lines = chunks.each_with_index.map do |chunk1, index|
|
37
|
+
next if processed.include? index
|
38
|
+
processed << index
|
39
|
+
chunk1 = chunk1
|
40
|
+
chunk2 = chunks[index + 1]
|
41
|
+
if not chunk2
|
42
|
+
next chunk1
|
43
|
+
end
|
44
|
+
|
45
|
+
chunk1 = ERB::Util.h(chunk1)
|
46
|
+
chunk2 = ERB::Util.h(chunk2)
|
47
|
+
|
48
|
+
dir1 = chunk1.each_char.first
|
49
|
+
dir2 = chunk2.each_char.first
|
50
|
+
case [dir1, dir2]
|
51
|
+
when ['-', '+']
|
52
|
+
line_diff = Dirb::Diff.new(
|
53
|
+
split_characters(chunk1),
|
54
|
+
split_characters(chunk2)
|
55
|
+
)
|
56
|
+
hi1 = reconstruct_characters(line_diff, '-')
|
57
|
+
hi2 = reconstruct_characters(line_diff, '+')
|
58
|
+
processed << (index + 1)
|
59
|
+
[hi1, hi2]
|
60
|
+
else
|
61
|
+
chunk1
|
62
|
+
end
|
63
|
+
end.flatten
|
64
|
+
lines.map{|line| line.each_line.map(&:chomp).to_a if line }.flatten.compact.
|
65
|
+
map{|line|wrap_line(line) }.compact
|
66
|
+
end
|
67
|
+
|
68
|
+
def split_characters(chunk)
|
69
|
+
chunk.gsub(/^./, '').each_line.map do |line|
|
70
|
+
line.chomp.split('') + ['\n']
|
71
|
+
end.flatten.join("\n")
|
72
|
+
end
|
73
|
+
|
74
|
+
def reconstruct_characters(line_diff, type)
|
75
|
+
line_diff.each_chunk.map do |l|
|
76
|
+
re = /(^|\\n)#{Regexp.escape(type)}/
|
77
|
+
case l
|
78
|
+
when re
|
79
|
+
"<strong>" + l.gsub(re, '').gsub("\n", '').
|
80
|
+
gsub('\n', "</strong>\n<strong>") + "</strong>"
|
81
|
+
when /^ /
|
82
|
+
l.gsub(/^./, '').gsub("\n", '').
|
83
|
+
gsub('\r', "\r").gsub('\n', "\n")
|
84
|
+
end
|
85
|
+
end.join('').split("\n").map do |l|
|
86
|
+
type + l
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/spec/dirb_spec.rb
CHANGED
@@ -1,7 +1,44 @@
|
|
1
1
|
require 'spec'
|
2
|
-
require File.join(File.dirname(__FILE__), '..', 'lib', 'dirb')
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'dirb'))
|
3
3
|
|
4
4
|
describe Dirb::Diff do
|
5
|
+
|
6
|
+
describe "diffing two files" do
|
7
|
+
def tempfile(string)
|
8
|
+
t = Tempfile.new('dirb-spec')
|
9
|
+
t.print(string)
|
10
|
+
t.flush
|
11
|
+
t.path
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should accept file paths as arguments" do
|
15
|
+
string1 = "foo\nbar\nbang\n"
|
16
|
+
string2 = "foo\nbang\n"
|
17
|
+
path1, path2 = tempfile(string1), tempfile(string2)
|
18
|
+
Dirb::Diff.new(path1, path2, :source => 'files').to_s.should == <<-DIFF
|
19
|
+
foo
|
20
|
+
-bar
|
21
|
+
bang
|
22
|
+
DIFF
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "with no line different" do
|
26
|
+
before do
|
27
|
+
string1 = "foo\nbar\nbang\n"
|
28
|
+
string2 = "foo\nbar\nbang\n"
|
29
|
+
@path1, @path2 = tempfile(string1), tempfile(string2)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should show everything" do
|
33
|
+
Dirb::Diff.new(@path1, @path2, :source => 'files').to_s.should == <<-DIFF
|
34
|
+
foo
|
35
|
+
bar
|
36
|
+
bang
|
37
|
+
DIFF
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
5
42
|
describe "#to_s" do
|
6
43
|
describe "with no line different" do
|
7
44
|
before do
|
@@ -104,8 +141,8 @@ describe Dirb::Diff do
|
|
104
141
|
DIFF
|
105
142
|
end
|
106
143
|
|
107
|
-
it "should make an awesome html diff" do
|
108
|
-
@diff.to_s(:
|
144
|
+
it "should make an awesome simple html diff" do
|
145
|
+
@diff.to_s(:html_simple).should == <<-HTML
|
109
146
|
<div class="diff">
|
110
147
|
<ul>
|
111
148
|
<li class="del"><del>foo</del></li>
|
@@ -122,7 +159,7 @@ describe Dirb::Diff do
|
|
122
159
|
end
|
123
160
|
|
124
161
|
it "should accept overrides to diff's options" do
|
125
|
-
@diff = Dirb::Diff.new(@string1, @string2, "--rcs")
|
162
|
+
@diff = Dirb::Diff.new(@string1, @string2, :diff => "--rcs")
|
126
163
|
@diff.to_s.should == <<-DIFF
|
127
164
|
d1 1
|
128
165
|
a1 3
|
@@ -136,6 +173,79 @@ baz
|
|
136
173
|
end
|
137
174
|
end
|
138
175
|
|
176
|
+
describe "html" do
|
177
|
+
|
178
|
+
it "should highlight the changes within the line" do
|
179
|
+
@string1 = "hahaha\ntime flies like an arrow\nfoo bar\nbang baz\n"
|
180
|
+
@string2 = "hahaha\nfruit flies like a banana\nbang baz\n"
|
181
|
+
@diff = Dirb::Diff.new(@string1, @string2)
|
182
|
+
html = <<-HTML
|
183
|
+
<div class="diff">
|
184
|
+
<ul>
|
185
|
+
<li class="unchanged"><span>hahaha</span></li>
|
186
|
+
<li class="del"><del><strong>t</strong>i<strong>me</strong> flies like a<strong>n arrow</strong></del></li>
|
187
|
+
<li class="del"><del><strong>foo</strong> ba<strong>r</strong></del></li>
|
188
|
+
<li class="ins"><ins><strong>fru</strong>i<strong>t</strong> flies like a ba<strong>nana</strong></ins></li>
|
189
|
+
<li class="unchanged"><span>bang baz</span></li>
|
190
|
+
</ul>
|
191
|
+
</div>
|
192
|
+
HTML
|
193
|
+
@diff.to_s(:html).should == html
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should not duplicate some lines" do
|
197
|
+
@string1 = "hahaha\ntime flies like an arrow\n"
|
198
|
+
@string2 = "hahaha\nfruit flies like a banana\nbang baz"
|
199
|
+
@diff = Dirb::Diff.new(@string1, @string2)
|
200
|
+
html = <<-HTML
|
201
|
+
<div class="diff">
|
202
|
+
<ul>
|
203
|
+
<li class="unchanged"><span>hahaha</span></li>
|
204
|
+
<li class="del"><del><strong>t</strong>i<strong>me</strong> flies like an a<strong>rrow</strong></del></li>
|
205
|
+
<li class="ins"><ins><strong>fru</strong>i<strong>t</strong> flies like a<strong> ba</strong>n<strong>ana</strong></ins></li>
|
206
|
+
<li class="ins"><ins><strong>bang</strong> <strong>b</strong>a<strong>z</strong></ins></li>
|
207
|
+
</ul>
|
208
|
+
</div>
|
209
|
+
HTML
|
210
|
+
@diff.to_s(:html).should == html
|
211
|
+
end
|
212
|
+
|
213
|
+
it "should escape html" do
|
214
|
+
@string1 = "ha<br>haha\ntime flies like an arrow\n"
|
215
|
+
@string2 = "ha<br>haha\nfruit flies like a banana\nbang baz"
|
216
|
+
@diff = Dirb::Diff.new(@string1, @string2)
|
217
|
+
html = <<-HTML
|
218
|
+
<div class="diff">
|
219
|
+
<ul>
|
220
|
+
<li class="unchanged"><span>ha<br>haha</span></li>
|
221
|
+
<li class="del"><del><strong>t</strong>i<strong>me</strong> flies like an a<strong>rrow</strong></del></li>
|
222
|
+
<li class="ins"><ins><strong>fru</strong>i<strong>t</strong> flies like a<strong> ba</strong>n<strong>ana</strong></ins></li>
|
223
|
+
<li class="ins"><ins><strong>bang</strong> <strong>b</strong>a<strong>z</strong></ins></li>
|
224
|
+
</ul>
|
225
|
+
</div>
|
226
|
+
HTML
|
227
|
+
@diff.to_s(:html).should == html
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should highlight the changes within the line with windows style line breaks" do
|
231
|
+
@string1 = "hahaha\r\ntime flies like an arrow\r\nfoo bar\r\nbang baz\n"
|
232
|
+
@string2 = "hahaha\r\nfruit flies like a banana\r\nbang baz\n"
|
233
|
+
@diff = Dirb::Diff.new(@string1, @string2)
|
234
|
+
html = <<-HTML
|
235
|
+
<div class="diff">
|
236
|
+
<ul>
|
237
|
+
<li class="unchanged"><span>hahaha</span></li>
|
238
|
+
<li class="del"><del><strong>t</strong>i<strong>me</strong> flies like a<strong>n arrow</strong></del></li>
|
239
|
+
<li class="del"><del><strong>foo</strong> ba<strong>r</strong></del></li>
|
240
|
+
<li class="ins"><ins><strong>fru</strong>i<strong>t</strong> flies like a ba<strong>nana</strong></ins></li>
|
241
|
+
<li class="unchanged"><span>bang baz</span></li>
|
242
|
+
</ul>
|
243
|
+
</div>
|
244
|
+
HTML
|
245
|
+
@diff.to_s(:html).should == html
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
139
249
|
it "should escape diffed html in html output" do
|
140
250
|
diff = Dirb::Diff.new("<script>alert('bar')</script>", "<script>alert('foo')</script>").to_s(:html)
|
141
251
|
diff.should include('<script>')
|
@@ -150,6 +260,18 @@ baz
|
|
150
260
|
end
|
151
261
|
end.compact.join.should == "line +baz added"
|
152
262
|
end
|
263
|
+
|
264
|
+
it "should let you iterate over chunks instead of lines" do
|
265
|
+
Dirb::Diff.new("foo\nbar\n", "foo\nbar\nbaz\n").each_chunk.map do |chunk|
|
266
|
+
chunk
|
267
|
+
end.should == [" foo\n bar\n", "+baz\n"]
|
268
|
+
end
|
269
|
+
|
270
|
+
it "should allow chaining enumerable methods" do
|
271
|
+
Dirb::Diff.new("foo\nbar\n", "foo\nbar\nbaz\n").each.map do |line|
|
272
|
+
line
|
273
|
+
end.should == [" foo\n", " bar\n", "+baz\n"]
|
274
|
+
end
|
153
275
|
end
|
154
276
|
end
|
155
277
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dirb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
|
-
-
|
8
|
-
- 1
|
7
|
+
- 2
|
9
8
|
- 0
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 2.0.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Sam Goldstein
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-11-20 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -37,6 +37,9 @@ files:
|
|
37
37
|
- VERSION
|
38
38
|
- dirb.gemspec
|
39
39
|
- lib/dirb.rb
|
40
|
+
- lib/dirb/diff.rb
|
41
|
+
- lib/dirb/format.rb
|
42
|
+
- lib/dirb/html_formatter.rb
|
40
43
|
- spec/dirb_spec.rb
|
41
44
|
has_rdoc: true
|
42
45
|
homepage: http://github.com/samg/dirb/tree/master
|