riffdiff 1.0.36 → 1.0.48

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: bcb6d863874cfd88533c0efabba5b2b475fab716
4
- data.tar.gz: 907345ad32b196b83ed2287cfe77e4c65b6747ce
3
+ metadata.gz: d95f2bec7e95f1926db693ed9995fc867fd387e3
4
+ data.tar.gz: 9863771e381648a0f786020691e77652948aa14b
5
5
  SHA512:
6
- metadata.gz: 3f3ca9298aa7fbf023c80b5326b77911ca5dcc0c9d09b52bbd43d3d54ecd064c78ae9326ea42376f49415e0807ac0b549ab005f34e05c8c3fead907b252fcee8
7
- data.tar.gz: 266d9594e38e8ec4254eddab4fc697a6f1a265d3b3e32a85260fef146a47b16b4c71fb179d55ff9b7993c52f3259b5529ab478c19dc2502edbd29c75b7c242f2
6
+ metadata.gz: 37ffcb842e39e386e019d56dff9bcefd5e6720aef94210fe6e325c5286923cdc27f2b70b327e654334697b0c323bf83b535b3399d453461e745f373285bdea4d
7
+ data.tar.gz: 6e8ff4707345cf558dd5495039dcd6096ad40c0c77ec0e613891a0eeb08da31a26143283be1918e634f76c89f6b979e5052f1b8de0c6d7dd9204b1c5335c22bf
data/.rubocop.yml CHANGED
@@ -45,3 +45,6 @@ Metrics/CyclomaticComplexity:
45
45
  # Configuration parameters: CountKeywordArgs.
46
46
  Metrics/ParameterLists:
47
47
  CountKeywordArgs: false
48
+
49
+ Metrics/ClassLength:
50
+ Max: 132
data/README.md CHANGED
@@ -25,9 +25,10 @@ Optionally followed by...
25
25
  # TODO
26
26
  * Think about highlighting whitespace errors like Git does
27
27
  * OK: Make DiffString.add() take a color as well
28
- * Add a whitespace analysis pass to the Refiner
29
- * Let the Refiner highlight whitespace errors among the added lines in reverse
30
- red.
28
+ * OK: Add a trailing whitespace analysis pass to the Refiner
29
+ * OK: Let the Refiner highlight whitespace errors among the added lines in
30
+ reverse red.
31
+ * Add highlighting of non-leading tabs to the whitespace analysis
31
32
  * Think about how to visualize an added line break together with some
32
33
  indentation on the following line.
33
34
  * Do "git show 57f27da" and think about what rule we should use to get
data/lib/refiner.rb CHANGED
@@ -2,6 +2,9 @@ require 'set'
2
2
  require 'diff/lcs'
3
3
  require 'diff_string'
4
4
 
5
+ require 'colors'
6
+ require 'whitespace_lint'
7
+
5
8
  # Compute longest common substring based diff between two strings.
6
9
  #
7
10
  # The diff format is first the old string:
@@ -15,6 +18,7 @@ require 'diff_string'
15
18
  # * added characters highlighted in inverse video
16
19
  class Refiner
17
20
  include Colors
21
+ include WhitespaceLint
18
22
 
19
23
  attr_reader :refined_old
20
24
  attr_reader :refined_new
@@ -33,7 +37,7 @@ class Refiner
33
37
  when '+'
34
38
  new_highlights << highlight.position
35
39
  else
36
- fail("Unsupported diff type: <#{type}>")
40
+ fail("Unsupported diff action: <#{action}>")
37
41
  end
38
42
  end
39
43
  end
@@ -95,28 +99,44 @@ class Refiner
95
99
  return try_highlight(old, new)
96
100
  end
97
101
 
98
- def render_refinement(prefix, color, string, highlights,
99
- base_index: 0, highlight_color: '')
100
- return_me = DiffString.new(prefix, color)
102
+ # ws: a set containing the whitespace errors we want to highlight
103
+ def render_refinement(prefix, base_color, string, highlights,
104
+ base_index: 0, highlight_color: '',
105
+ ws: nil)
106
+ return_me = DiffString.new(prefix, base_color)
101
107
  string.each_char.with_index do |char, index|
102
108
  highlight = highlights.include?(index + base_index)
103
- return_me.add(char, highlight, highlight ? highlight_color : '')
109
+ color = highlight ? highlight_color : ''
110
+
111
+ if !ws.nil? && ws.include?(index + base_index)
112
+ # Highlight whitespace error in inverse red
113
+ color = RED
114
+ highlight = true
115
+ end
116
+
117
+ return_me.add(char, highlight, color)
104
118
  end
105
119
  return return_me.to_s
106
120
  end
107
121
 
108
122
  # After returning from this method, both @refined_old and @refined_new must
109
123
  # have been set to reasonable values.
110
- def create_refinements(old, new, old_highlights, new_highlights)
124
+ def create_refinements(old, new,
125
+ old_highlights, new_highlights,
126
+ whitespace_highlights)
111
127
  @refined_old = render_refinement('-', RED, old, old_highlights)
112
- @refined_new = render_refinement('+', GREEN, new, new_highlights)
128
+ @refined_new = render_refinement('+', GREEN,
129
+ new, new_highlights,
130
+ ws: whitespace_highlights)
113
131
  end
114
132
 
115
133
  # After returning from this method, both @refined_old and @refined_new must
116
134
  # have been set to reasonable values.
117
135
  #
118
136
  # Returns false if the preconditions for using this method aren't fulfilled
119
- def create_one_to_many_refinements(old, new, old_highlights, new_highlights)
137
+ def create_one_to_many_refinements(old, new,
138
+ old_highlights, new_highlights,
139
+ whitespace_highlights)
120
140
  # If things have been removed from the first line, the specialized
121
141
  # highlighting won't work
122
142
  return false if old_highlights.count > 0
@@ -136,13 +156,15 @@ class Refiner
136
156
 
137
157
  refined_line_1 =
138
158
  render_refinement(' ', '', lines[0], new_highlights,
139
- highlight_color: GREEN)
159
+ highlight_color: GREEN,
160
+ ws: whitespace_highlights)
140
161
 
141
162
  line_2_index_0 = lines[0].length
142
163
  refined_remaining_lines = render_refinement('+', GREEN,
143
164
  lines[1..-1].join,
144
165
  new_highlights,
145
- base_index: line_2_index_0)
166
+ base_index: line_2_index_0,
167
+ ws: whitespace_highlights)
146
168
 
147
169
  @refined_new = refined_line_1 + refined_remaining_lines
148
170
 
@@ -155,10 +177,15 @@ class Refiner
155
177
  old_highlights, new_highlights = try_highlight_initial_lines(old, new)
156
178
  end
157
179
 
180
+ whitespace_highlights = collect_ws_highlights(new)
181
+
158
182
  if !create_one_to_many_refinements(old, new,
159
183
  old_highlights,
160
- new_highlights)
161
- create_refinements(old, new, old_highlights, new_highlights)
184
+ new_highlights,
185
+ whitespace_highlights)
186
+ create_refinements(old, new,
187
+ old_highlights, new_highlights,
188
+ whitespace_highlights)
162
189
  end
163
190
  end
164
191
  end
data/lib/riff.rb CHANGED
@@ -4,8 +4,6 @@ require 'diff_string'
4
4
 
5
5
  # Call do_stream() with the output of some diff-like tool (diff,
6
6
  # diff3, git diff, ...) and it will highlight that output for you.
7
- #
8
- # rubocop:disable Metrics/ClassLength
9
7
  class Riff
10
8
  DIFF_HEADER = /^diff /
11
9
  DIFF_HUNK_HEADER = /^@@ /
@@ -0,0 +1,34 @@
1
+ # Whitespace error linter
2
+ module WhitespaceLint
3
+ def add_line_highlights(line, base_index, highlights)
4
+ last_seen_whitespace = -1
5
+ last_seen_non_ws = -1
6
+ line.each_char.with_index do |char, index|
7
+ break if char == "\n"
8
+ break if char == "\r"
9
+
10
+ if char == ' ' || char == "\t"
11
+ last_seen_whitespace = index
12
+ else
13
+ last_seen_non_ws = index
14
+ end
15
+ end
16
+
17
+ if last_seen_non_ws < last_seen_whitespace
18
+ ((last_seen_non_ws + 1)..last_seen_whitespace).each do |index|
19
+ highlights << (base_index + index)
20
+ end
21
+ end
22
+ end
23
+
24
+ def collect_ws_highlights(string)
25
+ highlights = Set.new()
26
+ line_start_index = 0
27
+ string.each_line do |line|
28
+ add_line_highlights(line, line_start_index, highlights)
29
+
30
+ line_start_index += line.length
31
+ end
32
+ return highlights
33
+ end
34
+ end
data/spec/refiner_spec.rb CHANGED
@@ -65,6 +65,52 @@ RSpec.describe Refiner, '#new' do
65
65
  end
66
66
  end
67
67
 
68
+ context %(adding line with text + space) do
69
+ refiner = Refiner.new('', "text \n")
70
+
71
+ it %(highlights the final space in inverse red) do
72
+ expect(refiner.refined_new).to eq(
73
+ %(#{GREEN}+text#{reversed("#{RED} ")}#{GREEN}#{RESET}\n))
74
+ end
75
+ end
76
+
77
+ context %(adding two lines, second with text + space) do
78
+ refiner = Refiner.new('', "text\ntext \n")
79
+
80
+ it %(highlights the final space in inverse red) do
81
+ expect(refiner.refined_new).to eq(
82
+ %(#{GREEN}+text\n) +
83
+ %(#{GREEN}+text#{reversed("#{RED} ")}#{GREEN}#{RESET}\n))
84
+ end
85
+ end
86
+
87
+ context %(adding line with only a space) do
88
+ refiner = Refiner.new('', " \n")
89
+
90
+ it %(highlights the space in inverse red) do
91
+ expect(refiner.refined_new).to eq(
92
+ %(#{GREEN}+#{reversed("#{RED} ")}#{GREEN}#{RESET}\n))
93
+ end
94
+ end
95
+
96
+ context %(adding line with only a tab) do
97
+ refiner = Refiner.new('', "\t\n")
98
+
99
+ it %(highlights the tab in inverse red) do
100
+ expect(refiner.refined_new).to eq(
101
+ %(#{GREEN}+#{reversed("#{RED}\t")}#{GREEN}#{RESET}\n))
102
+ end
103
+ end
104
+
105
+ context %(replacing final char of line with a space) do
106
+ refiner = Refiner.new("text\n", "tex \n")
107
+
108
+ it %(highlights final space of added line in inverse red) do
109
+ expect(refiner.refined_new).to eq(
110
+ %(#{GREEN}+tex#{reversed("#{RED} ")}#{GREEN}#{RESET}\n))
111
+ end
112
+ end
113
+
68
114
  context %(with added ending newline) do
69
115
  refiner = Refiner.new('abcde',
70
116
  "abcde\n")
@@ -0,0 +1,47 @@
1
+ require 'whitespace_lint'
2
+
3
+ include WhitespaceLint
4
+
5
+ RSpec.describe WhitespaceLint, '#collect_ws_highlights' do
6
+ context 'empty string' do
7
+ it 'returns an empty set' do
8
+ expect(collect_ws_highlights('')).to be_empty
9
+ end
10
+ end
11
+
12
+ context 'a line that is fine' do
13
+ it 'returns an empty set' do
14
+ expect(collect_ws_highlights("\t text\n")).to be_empty
15
+ end
16
+ end
17
+
18
+ context 'line with only a space' do
19
+ it 'highlights the space' do
20
+ expect(collect_ws_highlights(" \n")).to eq(Set.new [0])
21
+ end
22
+ end
23
+
24
+ context 'line with only a tab' do
25
+ it 'highlights the tab' do
26
+ expect(collect_ws_highlights("\t\n")).to eq(Set.new [0])
27
+ end
28
+ end
29
+
30
+ context 'line with text + space' do
31
+ it 'highlights the space' do
32
+ expect(collect_ws_highlights("012 \n")).to eq(Set.new [3])
33
+ end
34
+ end
35
+
36
+ context 'two lines, second ending in space' do
37
+ string = "012\n345 \n"
38
+
39
+ it 'highlights the space' do
40
+ highlights = collect_ws_highlights(string)
41
+ expect(highlights.size).to eq(1)
42
+
43
+ highlight = highlights.to_a()[0]
44
+ expect(string[highlight]).to eq(' ')
45
+ end
46
+ end
47
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riffdiff
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.36
4
+ version: 1.0.48
5
5
  platform: ruby
6
6
  authors:
7
7
  - Johan Walles
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-02 00:00:00.000000000 Z
11
+ date: 2015-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -119,6 +119,7 @@ files:
119
119
  - lib/refiner.rb
120
120
  - lib/riff.rb
121
121
  - lib/version.rb
122
+ - lib/whitespace_lint.rb
122
123
  - riffdiff.gemspec
123
124
  - spec/added-newline-at-eof.diff
124
125
  - spec/colors_spec.rb
@@ -129,6 +130,7 @@ files:
129
130
  - spec/removed-newline-at-eof.diff
130
131
  - spec/riff_spec.rb
131
132
  - spec/version_spec.rb
133
+ - spec/whitespace_lint_spec.rb
132
134
  homepage: http://github.com/walles/riff
133
135
  licenses:
134
136
  - MIT
@@ -163,3 +165,4 @@ test_files:
163
165
  - spec/removed-newline-at-eof.diff
164
166
  - spec/riff_spec.rb
165
167
  - spec/version_spec.rb
168
+ - spec/whitespace_lint_spec.rb