pretty_diff 2.0.1 → 2.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c5d1f835ae8a57aac2ad92f1d48d993dddfddc9a
4
- data.tar.gz: 11ceb7a5777734a552fc0f0635f6b605a2ae9990
3
+ metadata.gz: aa8fdb38ef57b9d401bd02d8755fd35c12f1b328
4
+ data.tar.gz: 7813678ca54211816a9a7c484b837b718548623a
5
5
  SHA512:
6
- metadata.gz: 89316d8b0c1f972a8adf6baf7f6fa3d55903f8bb648eaa6eb8587070328be015530495495baf6263bf2f4691b56ff26e74745dd418cdf78d111c9cc756469319
7
- data.tar.gz: 1d5d2ab3bf30422b7b95d2fa3b0c9cc9cd1dcbac53bcb7a238a9953f7bfe0f20ca0e506d90ca46439322a7889f387714f7e1f652170caf4aaacba1fa6f4d3d66
6
+ metadata.gz: e103bae389f4f3433db7ced131e764490ce97f9c9c2f19ecf377e92baf37164016c847f037d12cf7f52ba272803163a25a98e8ef5e5affd26e03299c1540fd86
7
+ data.tar.gz: 9b3af1e0b269f1c5f259b2962e8ff9d2e71c1fb17fa2806d1de45ba61623466d74d137096a753c45b9ca788a2f333138f4fcf9b0bc6892b1ad05a95dc865e69c
data/Gemfile CHANGED
@@ -1,8 +1,3 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem "charlock_holmes", "~> 0.6"
4
-
5
- group :development do
6
- gem "jeweler"
7
- gem "builder"
8
- end
3
+ gemspec
@@ -1,9 +1,15 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ pretty_diff (2.1.0)
5
+ pretty_diff
6
+
1
7
  GEM
2
8
  remote: http://rubygems.org/
3
9
  specs:
4
10
  addressable (2.3.5)
11
+ ansi (1.4.3)
5
12
  builder (3.1.4)
6
- charlock_holmes (0.6.9.1)
7
13
  descendants_tracker (0.0.3)
8
14
  faraday (0.9.0)
9
15
  multipart-post (>= 1.2, < 3)
@@ -46,11 +52,14 @@ GEM
46
52
  rake (10.1.1)
47
53
  rdoc (4.1.1)
48
54
  json (~> 1.4)
55
+ turn (0.9.6)
56
+ ansi
49
57
 
50
58
  PLATFORMS
51
59
  ruby
52
60
 
53
61
  DEPENDENCIES
54
62
  builder
55
- charlock_holmes (~> 0.6)
56
63
  jeweler
64
+ pretty_diff!
65
+ turn
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.1
1
+ 2.1.0
@@ -1,5 +1,5 @@
1
1
  module PrettyDiff
2
- class InvalidGenerator < Exception; end
2
+ class InvalidGeneratorError < Exception; end
3
3
  end
4
4
 
5
5
  def require_local(suffix)
@@ -11,5 +11,6 @@ require_local 'pretty_diff/diff'
11
11
  require_local 'pretty_diff/chunk'
12
12
  require_local 'pretty_diff/line_numbers'
13
13
  require_local 'pretty_diff/line'
14
+ require_local 'pretty_diff/word_diff_finder'
14
15
  require_local 'pretty_diff/abstract_generator'
15
16
  require_local 'pretty_diff/basic_generator'
@@ -15,9 +15,13 @@ module PrettyDiff
15
15
 
16
16
  private
17
17
 
18
+ def wdiff(lines)
19
+ PrettyDiff::WordDiffFinder.find_word_diffs(lines)
20
+ end
21
+
18
22
  def find_lines
19
23
  [].tap do |lines|
20
- contents.split(/\r?\n|\r/).each do |line_str|
24
+ wdiff(contents.split(/\r?\n|\r/)).each do |line_str|
21
25
  line = Line.new(self, line_str)
22
26
  next if line.ignored?
23
27
  lines << line
@@ -26,7 +26,7 @@ module PrettyDiff
26
26
  @unified_diff = unified_diff
27
27
  @options = options
28
28
  @out_encoding =
29
- @generator = validate_generator(options[:generator]) || BasicGenerator
29
+ @generator = validate_generator( options[:generator] || BasicGenerator )
30
30
  @out_encoding = options[:out_encoding] || 'utf-8'
31
31
  end
32
32
 
@@ -73,7 +73,7 @@ module PrettyDiff
73
73
  if valid_generator?(gen)
74
74
  gen
75
75
  else
76
- raise InvalidGenerator, "#{gen.inspect} is not a valid PrettyDiff generator"
76
+ raise InvalidGeneratorError, "#{gen.inspect} is not a valid PrettyDiff generator"
77
77
  end
78
78
  end
79
79
 
@@ -34,6 +34,5 @@ module PrettyDiff
34
34
  def not_modified?
35
35
  status == :not_modified
36
36
  end
37
-
38
37
  end
39
38
  end
@@ -0,0 +1,130 @@
1
+ require 'levenshtein'
2
+ require 'diff_match_patch_native'
3
+
4
+ module PrettyDiff
5
+ module WordDiffFinder
6
+ WDIFF_INSERTED_START = "\x01"
7
+ WDIFF_INSERTED_END = "\x02"
8
+ WDIFF_DELETED_START = "\x03"
9
+ WDIFF_DELETED_END = "\x04"
10
+
11
+ extend self
12
+
13
+ def find_word_diffs(lines)
14
+ dmp = DiffMatchPatch.new
15
+ result = []
16
+ added_next_line_already = false
17
+
18
+ lines.each_with_index do |line, idx|
19
+ if added_next_line_already
20
+ added_next_line_already = false
21
+ next
22
+ end
23
+
24
+ previous_line = idx > 0 ? lines[idx - 1] : nil
25
+ stripped_line = strip(line)
26
+ next_line = lines[idx + 1]
27
+ stripped_next_line = strip(next_line || '')
28
+ after_next_line = idx < lines.size ? lines[idx + 2] : nil
29
+
30
+ # only show word diffing when change was a single line
31
+ if changed_line?(line, next_line) && !changed_block?(previous_line, line, next_line, after_next_line) && similiar_lines?(stripped_line, stripped_next_line)
32
+ diffs = dmp.diff_cleanup_semantic!(dmp.diff_main(stripped_line, stripped_next_line, true))
33
+ replacement, next_replacement = join_diffs(diffs)
34
+
35
+ if line.include?(replacement.first)
36
+ # String#gsub in the form gsub(exp,replacement) has odd quirks
37
+ # affecting the replacement string which sometimes require
38
+ # lots of escaping slashes. Ruby users are frequently directed
39
+ # to use the block form instead.
40
+ # See: http://stackoverflow.com/a/13818467/204927
41
+ line.gsub!(replacement.first) { replacement.last }
42
+ else # it has to come form next_line
43
+ next_line.gsub!(replacement.first) { replacement.last }
44
+ added_next_line_already = true
45
+ end
46
+
47
+ if next_line && next_replacement
48
+ next_line.gsub!(next_replacement.first) { next_replacement.last }
49
+ added_next_line_already = true
50
+ end
51
+ end
52
+
53
+ result << line
54
+
55
+ if added_next_line_already
56
+ result << next_line
57
+ end
58
+ end
59
+
60
+ result
61
+ end
62
+
63
+ private
64
+
65
+ def to_utf8(str)
66
+ str.force_encoding('utf-8')
67
+ end
68
+
69
+ def wrap_in_inserted_tokens(str)
70
+ "#{WDIFF_INSERTED_START}#{str}#{WDIFF_INSERTED_END}"
71
+ end
72
+
73
+ def wrap_in_deleted_tokens(str)
74
+ "#{WDIFF_DELETED_START}#{str}#{WDIFF_DELETED_END}"
75
+ end
76
+
77
+ def join_diffs(diffs)
78
+ inserted, deleted = '', ''
79
+ inserted_with_token, deleted_with_token = '', ''
80
+
81
+ operations = diffs.map(&:first)
82
+ # inline change
83
+ if ( operations.include?(1) && !operations.include?(-1) ) || ( operations.include?(-1) && !operations.include?(1) )
84
+ diffs.each do |diff|
85
+ deleted += diff.last
86
+ if diff.first == 0 # didn't change
87
+ deleted_with_token += diff.last
88
+ elsif diff.first == 1 # inserted
89
+ deleted_with_token += wrap_in_inserted_tokens(diff.last)
90
+ elsif diff.first == -1 # deleted
91
+ deleted_with_token += wrap_in_deleted_tokens(diff.last)
92
+ end
93
+ end
94
+ else
95
+ diffs.each do |diff|
96
+ if diff.first == 0 # didn't change
97
+ inserted += diff.last
98
+ deleted += diff.last
99
+ inserted_with_token += diff.last
100
+ deleted_with_token += diff.last
101
+ elsif diff.first == 1 # inserted
102
+ inserted += diff.last
103
+ inserted_with_token += wrap_in_inserted_tokens(diff.last)
104
+ elsif diff.first == -1 # deleted
105
+ deleted += diff.last
106
+ deleted_with_token += wrap_in_deleted_tokens(diff.last)
107
+ end
108
+ end
109
+ end
110
+
111
+ [[to_utf8(deleted), to_utf8(deleted_with_token)], [to_utf8(inserted), to_utf8(inserted_with_token)]]
112
+ end
113
+
114
+ def strip(line)
115
+ line[1..-1]
116
+ end
117
+
118
+ def changed_line?(line, next_line)
119
+ (line =~ /^-/ && next_line =~ /^\+/)
120
+ end
121
+
122
+ def changed_block?(previous_line, line, next_line, after_next_line)
123
+ (previous_line =~ /^-/ && line =~ /^-/ && next_line =~ /^\+/ && after_next_line =~ /^\+/)
124
+ end
125
+
126
+ def similiar_lines?(first, second)
127
+ Levenshtein.distance(first, second) <= [first.size, second.size].max * 0.60
128
+ end
129
+ end
130
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "pretty_diff"
8
- s.version = "2.0.1"
8
+ s.version = "2.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ilya Sabanin"]
12
- s.date = "2014-02-18"
12
+ s.date = "2014-02-21"
13
13
  s.description = "PrettyDiff is a highly customizable library for creating fully featured HTML\n listings out of unified diff format strings.\n Include copy/paste-safe line numbers and built-in syntax highlighting."
14
14
  s.email = "ilya.sabanin@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -32,6 +32,7 @@ Gem::Specification.new do |s|
32
32
  "lib/pretty_diff/encoding.rb",
33
33
  "lib/pretty_diff/line.rb",
34
34
  "lib/pretty_diff/line_numbers.rb",
35
+ "lib/pretty_diff/word_diff_finder.rb",
35
36
  "pretty_diff.gemspec",
36
37
  "test/abstract_generator_test.rb",
37
38
  "test/basic_generator_test.rb",
@@ -46,15 +47,21 @@ Gem::Specification.new do |s|
46
47
  "test/fixtures/csharp.diff.html",
47
48
  "test/fixtures/first.diff",
48
49
  "test/fixtures/first.diff.html",
50
+ "test/fixtures/inline_change.diff",
51
+ "test/fixtures/mid_sized_change.diff",
52
+ "test/fixtures/quick_change.diff",
49
53
  "test/fixtures/second.diff",
50
54
  "test/fixtures/single_line.diff",
51
55
  "test/fixtures/single_line.diff.html",
56
+ "test/fixtures/space_change.diff",
57
+ "test/fixtures/special_characters.diff",
52
58
  "test/fixtures/text.diff",
53
59
  "test/fixtures/text.diff.html",
54
60
  "test/fixtures/windows-cp1251-lf",
55
61
  "test/helper.rb",
56
62
  "test/line_numbers_test.rb",
57
- "test/line_test.rb"
63
+ "test/line_test.rb",
64
+ "test/word_diff_finder_test.rb"
58
65
  ]
59
66
  s.homepage = "http://github.com/isabanin/pretty_diff"
60
67
  s.require_paths = ["lib"]
@@ -65,18 +72,21 @@ Gem::Specification.new do |s|
65
72
  s.specification_version = 4
66
73
 
67
74
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
68
- s.add_runtime_dependency(%q<charlock_holmes>, ["~> 0.6"])
75
+ s.add_runtime_dependency(%q<pretty_diff>, [">= 0"])
69
76
  s.add_development_dependency(%q<jeweler>, [">= 0"])
70
77
  s.add_development_dependency(%q<builder>, [">= 0"])
78
+ s.add_development_dependency(%q<turn>, [">= 0"])
71
79
  else
72
- s.add_dependency(%q<charlock_holmes>, ["~> 0.6"])
80
+ s.add_dependency(%q<pretty_diff>, [">= 0"])
73
81
  s.add_dependency(%q<jeweler>, [">= 0"])
74
82
  s.add_dependency(%q<builder>, [">= 0"])
83
+ s.add_dependency(%q<turn>, [">= 0"])
75
84
  end
76
85
  else
77
- s.add_dependency(%q<charlock_holmes>, ["~> 0.6"])
86
+ s.add_dependency(%q<pretty_diff>, [">= 0"])
78
87
  s.add_dependency(%q<jeweler>, [">= 0"])
79
88
  s.add_dependency(%q<builder>, [">= 0"])
89
+ s.add_dependency(%q<turn>, [">= 0"])
80
90
  end
81
91
  end
82
92
 
@@ -4,26 +4,26 @@ class BasicGeneratorTest < MiniTest::Unit::TestCase
4
4
 
5
5
  def test_generated_html
6
6
  diff = new_diff(fixture('first.diff'), :generator => PrettyDiff::BasicGenerator)
7
- assert_equal fixture('first.diff.html'), diff.to_html
7
+ assert_equal fixture('first.diff.html'), strip_word_indicators(diff.to_html)
8
8
  end
9
9
 
10
10
  def test_more_generated_html
11
11
  diff = new_diff(fixture('text.diff'), :generator => PrettyDiff::BasicGenerator)
12
- assert_equal fixture('text.diff.html'), diff.to_html
12
+ assert_equal fixture('text.diff.html'), strip_word_indicators(diff.to_html)
13
13
  end
14
14
 
15
15
  def test_another_generated_html
16
16
  diff = new_diff(fixture('csharp.diff'), :generator => PrettyDiff::BasicGenerator)
17
- assert_equal fixture('csharp.diff.html'), diff.to_html
17
+ assert_equal fixture('csharp.diff.html'), strip_word_indicators(diff.to_html)
18
18
  end
19
19
 
20
20
  def test_generate_html_for_blank
21
21
  diff = new_diff(fixture('blank.diff'), :generator => PrettyDiff::BasicGenerator)
22
- assert_equal fixture('blank.diff.html'), diff.to_html
22
+ assert_equal fixture('blank.diff.html'), strip_word_indicators(diff.to_html)
23
23
  end
24
24
 
25
25
  def test_generate_html_for_single_line_diffs
26
26
  diff = new_diff(fixture('single_line.diff'), :generator => PrettyDiff::BasicGenerator)
27
- assert_equal fixture('single_line.diff.html'), diff.to_html
27
+ assert_equal fixture('single_line.diff.html'), strip_word_indicators(diff.to_html)
28
28
  end
29
29
  end
@@ -36,7 +36,7 @@ class DiffTest < MiniTest::Unit::TestCase
36
36
  end
37
37
 
38
38
  def test_invalid_custom_generator
39
- assert_raises PrettyDiff::InvalidGenerator do
39
+ assert_raises PrettyDiff::InvalidGeneratorError do
40
40
  new_diff('bla', :generator => NotAGenerator)
41
41
  end
42
42
 
@@ -0,0 +1,29 @@
1
+ @@ -130,7 +130,7 @@ class GroovyImage {
2
+ graph.drawImage(image,new AffineTransform(1.0d,0.0d,0.0d,1.0d,left,top),null);
3
+ def parsed Width = parseValue(width,image.width,true,"100%");
4
+ return newImage;
5
+ -
6
+ +
7
+ }
8
+
9
+ BufferedImage parseAndFit(image,width,height) {
10
+ @@ -274,15 +274,17 @@ class GroovyImage {
11
+ switch(type) {
12
+ case "px":
13
+ return decimalValue / size;
14
+ - case "%":
15
+ + case "percent":
16
+ return decimalValue / 100;
17
+ + case "%":
18
+ + return decimalValue / 100;
19
+ default:
20
+ return decimalValue;
21
+ }
22
+ }
23
+ }
24
+
25
+ - Object argsLength(args,length) {
26
+ + Object argsLength(args,lengths) {
27
+ if(args.size() < length) {
28
+ while(args.size() < length) {
29
+ args.add("change");
@@ -0,0 +1,109 @@
1
+ diff --git a/Core/Contents/Source/PolySceneLine.cpp b/Core/Contents/Source/PolySceneLine.cpp
2
+ index 6c374f2..3d3adc7 100755
3
+ --- a/Core/Contents/Source/PolySceneLine.cpp
4
+ +++ b/Core/Contents/Source/PolySceneLine.cpp
5
+ @@ -26,43 +26,29 @@
6
+
7
+ using namespace Polycode;
8
+
9
+ -SceneLine::SceneLine(Vector3 start, Vector3 end) : SceneEntity() {
10
+ +SceneLine::SceneLine(Vector3 start, Vector3 end) : SceneMesh(Mesh::LINE_MESH) {
11
+ this->ent1 = NULL;
12
+ - this->ent2 = NULL;
13
+ -
14
+ + this->ent2 = NULL;
15
+ this->start = start;
16
+ this->end = end;
17
+ -
18
+ - mesh = new Mesh(Mesh::LINE_MESH);
19
+ -
20
+ - Polygon *poly = new Polygon();
21
+ - poly->addVertex(0,0,0);
22
+ - poly->addVertex(0,0,0);
23
+ - mesh->addPolygon(poly);
24
+ -
25
+ + initLine();
26
+ ignoreParentMatrix = true;
27
+ -
28
+ - lineWidth = 1.0;
29
+ - lineSmooth = false;
30
+ -
31
+ }
32
+
33
+ -SceneLine::SceneLine(SceneEntity *ent1, SceneEntity *ent2) : SceneEntity() {
34
+ +SceneLine::SceneLine(SceneEntity *ent1, SceneEntity *ent2) : SceneMesh(Mesh::LINE_MESH) {
35
+ this->ent1 = ent1;
36
+ this->ent2 = ent2;
37
+ + initLine();
38
+ + ignoreParentMatrix = true;
39
+
40
+ - mesh = new Mesh(Mesh::LINE_MESH);
41
+ -
42
+ +}
43
+ +
44
+ +void SceneLine::initLine() {
45
+ Polygon *poly = new Polygon();
46
+ - poly->addVertex(0,0,0);
47
+ - poly->addVertex(0,0,0);
48
+ + poly->addVertex(0,0,0,0,0);
49
+ + poly->addVertex(0,0,0,1,0);
50
+ mesh->addPolygon(poly);
51
+ -
52
+ - ignoreParentMatrix = true;
53
+ -
54
+ - lineWidth = 1.0;
55
+ - lineSmooth = false;
56
+ -
57
+ + mesh->arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
58
+ }
59
+
60
+ SceneLine *SceneLine::SceneLineWithPositions(Vector3 start, Vector3 end) {
61
+ @@ -70,7 +56,6 @@ SceneLine *SceneLine::SceneLineWithPositions(Vector3 start, Vector3 end) {
62
+ }
63
+
64
+ SceneLine::~SceneLine() {
65
+ - delete mesh;
66
+ }
67
+
68
+ void SceneLine::setStart(Vector3 start) {
69
+ @@ -81,11 +66,11 @@ void SceneLine::setEnd(Vector3 end) {
70
+ this->end = end;
71
+ }
72
+
73
+ -void SceneLine::Render() {
74
+ +void SceneLine::Update(){
75
+
76
+ Vector3 v1;
77
+ - Vector3 v2;
78
+ -
79
+ + Vector3 v2;
80
+ +
81
+ if(ent1 != NULL && ent2 != NULL) {
82
+ v1 = ent1->getConcatenatedMatrix().getPosition();
83
+ v2 = ent2->getConcatenatedMatrix().getPosition();
84
+ @@ -93,22 +78,8 @@ void SceneLine::Render() {
85
+ v1 = start;
86
+ v2 = end;
87
+ }
88
+ -
89
+ -
90
+ - mesh->getPolygon(0)->getVertex(0)->set(v1.x,v1.y,v1.z);
91
+ - mesh->getPolygon(0)->getVertex(1)->set(v2.x,v2.y,v2.z);
92
+ - mesh->arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
93
+ -
94
+ - Renderer *renderer = CoreServices::getInstance()->getRenderer();
95
+ -
96
+ - renderer->setLineSize(lineWidth);
97
+ - renderer->setLineSmooth(lineSmooth);
98
+ -
99
+ - renderer->setTexture(NULL);
100
+ - renderer->pushDataArrayForMesh(mesh, RenderDataArray::VERTEX_DATA_ARRAY);
101
+ - renderer->pushDataArrayForMesh(mesh, RenderDataArray::TEXCOORD_DATA_ARRAY);
102
+ - renderer->pushDataArrayForMesh(mesh, RenderDataArray::NORMAL_DATA_ARRAY);
103
+ -
104
+ - renderer->drawArrays(mesh->getMeshType());
105
+
106
+ + mesh->getPolygon(0)->getVertex(0)->set(v1.x,v1.y,v1.z);
107
+ + mesh->getPolygon(0)->getVertex(1)->set(v2.x,v2.y,v2.z);
108
+ + mesh->arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
109
+ }
@@ -0,0 +1,3 @@
1
+ @@ -1 +1 @@
2
+ -some example text
3
+ +testsome example text
@@ -0,0 +1,9 @@
1
+ @@ -127,7 +127,7 @@ class GroovyImage {
2
+ // createGraphics() needs a display, find workaround.
3
+ def graph = newImage.createGraphics();
4
+ graph.drawImage(image,new AffineTransform(1.0d,0.0d,0.0d,1.0d,left,top),null);
5
+ - def parsedWidth = parseValue(width,image.width,true,"100%");
6
+ + def parsed Width = parseValue(width,image.width,true,"100%");
7
+ return newImage;
8
+ }
9
+
@@ -0,0 +1,25 @@
1
+ @@ -54,11 +54,12 @@ class GroovyImage {
2
+
3
+ void addOperation(command) {
4
+
5
+ - def matcher = command =~ "([a-z]+)\\((.*)\\).*";
6
+ +/* 57 line */
7
+ + def matcher = command =~ "([a-z]+)\\((.*)\\).*";
8
+ matcher.find();
9
+
10
+ - def method = matcher.group(1);
11
+ - def args = matcher.group(2).split(",").toList();
12
+ + def method = matcher.group(1); /* 61 line */
13
+ + def args = matcher.group(62).split(",").toList();
14
+
15
+ switch(method) {
16
+ case "scale": // vertical,horizontal
17
+ @@ -79,7 +80,7 @@ class GroovyImage {
18
+ }
19
+ }
20
+
21
+ - BufferedImage parseAndRotate(image,degrees,x,y) {
22
+ + BufferedImage parseAndRotate(images83line,degrees,x,y) {
23
+ def parsedRadians = 0;
24
+ try {
25
+ parsedRadians = Math.toRadians(Double.parseDouble(degrees));
@@ -1,17 +1,34 @@
1
1
  require 'rubygems'
2
2
  require 'bundler/setup'
3
3
  require 'minitest/autorun'
4
+ require 'turn'
4
5
 
5
6
  require File.join(File.dirname(__FILE__), '..', 'lib', 'pretty_diff')
6
7
 
7
8
  class MiniTest::Unit::TestCase
9
+ include PrettyDiff::WordDiffFinder
10
+
11
+ class FixtureNotFoundError < StandardError; end
8
12
 
9
13
  def new_diff(*args)
10
14
  PrettyDiff::Diff.new(*args)
11
15
  end
12
16
 
13
17
  def fixture(name)
14
- File.read(File.join(File.dirname(__FILE__), "fixtures", name))
18
+ path = File.join(File.dirname(__FILE__), "fixtures", name)
19
+ if File.exist?(path)
20
+ File.read(path)
21
+ else
22
+ raise FixtureNotFoundError.new("Fixture at path '#{path}' was not found")
23
+ end
24
+ end
25
+
26
+ def strip_word_indicators(text)
27
+ text
28
+ .gsub(WDIFF_INSERTED_START, '')
29
+ .gsub(WDIFF_INSERTED_END, '')
30
+ .gsub(WDIFF_DELETED_START, '')
31
+ .gsub(WDIFF_DELETED_END, '')
15
32
  end
16
33
 
17
34
  end
@@ -8,10 +8,10 @@ class LineTest < MiniTest::Unit::TestCase
8
8
  end
9
9
 
10
10
  def test_contents
11
- assert_equal " color: #999;", @lines[0].contents
12
- assert_equal "- table.account-overview td .status {", @lines[3].contents
13
- assert_equal "+ table.account-overview td.label.top {", @lines[4].contents
14
- assert_equal " }", @lines.last.contents
11
+ assert_equal " color: #999;", strip_word_indicators(@lines[0].contents)
12
+ assert_equal "- table.account-overview td .status {", strip_word_indicators(@lines[3].contents)
13
+ assert_equal "+ table.account-overview td.label.top {", strip_word_indicators(@lines[4].contents)
14
+ assert_equal " }", strip_word_indicators(@lines.last.contents)
15
15
  end
16
16
 
17
17
  def test_ignored
@@ -0,0 +1,79 @@
1
+ require File.join(File.dirname(__FILE__), 'helper')
2
+
3
+ class WordDiffFinderTest < MiniTest::Unit::TestCase
4
+ def test_join_diff_from_dmp
5
+ diffs = [[0, " Object argsLength(args,length"], [1, "s"], [0, ") {\n"]]
6
+ expected = " Object argsLength(args,lengths) {\n"
7
+ expected_with_token = " Object argsLength(args,length#{wrap_in_inserted_tokens 's'}) {\n"
8
+ assert_equal [expected, expected_with_token], join_diffs(diffs).first
9
+
10
+ diffs = [[0, " case \""], [-1, "%"], [1, "percent"], [0, "\":\n"]]
11
+ expected_first = " case \"%\":\n"
12
+ expected_first_with_token = " case \"#{wrap_in_deleted_tokens '%'}\":\n"
13
+
14
+ expected_second = " case \"percent\":\n"
15
+ expected_second_with_token = " case \"#{wrap_in_inserted_tokens 'percent'}\":\n"
16
+
17
+ first, second = join_diffs(diffs)
18
+ assert_equal [expected_first, expected_first_with_token], first
19
+ assert_equal [expected_second, expected_second_with_token], second
20
+
21
+ diffs = [[-1, " "], [0, "\n"]]
22
+ expected = " \n"
23
+ expected_with_token = "#{wrap_in_deleted_tokens ' '}\n"
24
+ assert_equal [expected, expected_with_token], join_diffs(diffs).first
25
+ end
26
+
27
+ def test_highlighting_inline_diff
28
+ content = fixture('inline_change.diff').lines
29
+ lines_found = find_word_diffs(content)
30
+ assert_equal content.size, lines_found.size
31
+
32
+ # two inline delete highlighted
33
+ assert 2, num_of_tags(WDIFF_DELETED_START, lines_found)
34
+ # two inline insert highlighted
35
+ assert 2, num_of_tags(WDIFF_INSERTED_START, lines_found)
36
+ end
37
+
38
+ def test_highlighting_quick_diff
39
+ content = fixture('quick_change.diff').lines
40
+ lines_found = find_word_diffs(content)
41
+ assert_equal content.size, lines_found.size
42
+
43
+ assert lines_include_wrapped_content(lines_found, wrap_in_inserted_tokens('test'))
44
+ # one inline insert highlighted
45
+ assert_equal 1, num_of_tags(WDIFF_INSERTED_START, lines_found)
46
+ end
47
+
48
+ def test_highlighting_single_space_diff
49
+ content = fixture('space_change.diff').lines
50
+ lines_found = find_word_diffs(content)
51
+ assert_equal content.size, lines_found.size
52
+
53
+ assert lines_include_wrapped_content(lines_found, "parsed#{wrap_in_inserted_tokens ' '}Width")
54
+ # one inline insert highlighted
55
+ assert_equal 1, num_of_tags(WDIFF_INSERTED_START, lines_found)
56
+ end
57
+
58
+ def test_highlighting_special_character_diff
59
+ content = fixture('special_characters.diff').lines
60
+ lines_found = find_word_diffs(content)
61
+ assert_equal content.size, lines_found.size
62
+
63
+ assert lines_include_wrapped_content(lines_found, wrap_in_inserted_tokens("s83line"))
64
+
65
+ # one inline insert highlighted
66
+ assert_equal 1, num_of_tags(WDIFF_INSERTED_START, lines_found)
67
+ assert_equal 0, num_of_tags(WDIFF_DELETED_START, lines_found)
68
+ end
69
+
70
+ private
71
+
72
+ def lines_include_wrapped_content(lines, content)
73
+ lines.map(&:to_s).join("\n").include?(content)
74
+ end
75
+
76
+ def num_of_tags(tag, lines)
77
+ lines.join("\n").scan(/#{tag}/).size
78
+ end
79
+ end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pretty_diff
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ilya Sabanin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-18 00:00:00.000000000 Z
11
+ date: 2014-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: charlock_holmes
14
+ name: pretty_diff
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
- version: '0.6'
19
+ version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
- version: '0.6'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: jeweler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: turn
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  description: |-
56
70
  PrettyDiff is a highly customizable library for creating fully featured HTML
57
71
  listings out of unified diff format strings.
@@ -78,6 +92,7 @@ files:
78
92
  - lib/pretty_diff/encoding.rb
79
93
  - lib/pretty_diff/line.rb
80
94
  - lib/pretty_diff/line_numbers.rb
95
+ - lib/pretty_diff/word_diff_finder.rb
81
96
  - pretty_diff.gemspec
82
97
  - test/abstract_generator_test.rb
83
98
  - test/basic_generator_test.rb
@@ -92,15 +107,21 @@ files:
92
107
  - test/fixtures/csharp.diff.html
93
108
  - test/fixtures/first.diff
94
109
  - test/fixtures/first.diff.html
110
+ - test/fixtures/inline_change.diff
111
+ - test/fixtures/mid_sized_change.diff
112
+ - test/fixtures/quick_change.diff
95
113
  - test/fixtures/second.diff
96
114
  - test/fixtures/single_line.diff
97
115
  - test/fixtures/single_line.diff.html
116
+ - test/fixtures/space_change.diff
117
+ - test/fixtures/special_characters.diff
98
118
  - test/fixtures/text.diff
99
119
  - test/fixtures/text.diff.html
100
120
  - test/fixtures/windows-cp1251-lf
101
121
  - test/helper.rb
102
122
  - test/line_numbers_test.rb
103
123
  - test/line_test.rb
124
+ - test/word_diff_finder_test.rb
104
125
  homepage: http://github.com/isabanin/pretty_diff
105
126
  licenses: []
106
127
  metadata: {}