Commit 99c3e49e authored by Michael Kozono's avatar Michael Kozono

Merge branch '16950_use_marker_ranges_for_word_diff' into 'master'

Detect MarkerRanges for word-diff mode

See merge request gitlab-org/gitlab!56401
parents ee5a8a20 257987aa
...@@ -24,6 +24,12 @@ module Gitlab ...@@ -24,6 +24,12 @@ module Gitlab
Range.new(self.begin, self.end, self.exclude_end?) Range.new(self.begin, self.end, self.exclude_end?)
end end
def ==(other)
return false unless other.is_a?(self.class)
self.mode == other.mode && super
end
attr_reader :mode attr_reader :mode
end end
end end
...@@ -18,6 +18,27 @@ module Gitlab ...@@ -18,6 +18,27 @@ module Gitlab
def reset def reset
@chunks = [] @chunks = []
end end
def marker_ranges
start = 0
@chunks.each_with_object([]) do |element, ranges|
mode = mode_for_element(element)
ranges << Gitlab::MarkerRange.new(start, start + element.length - 1, mode: mode) if mode
start += element.length
end
end
private
def mode_for_element(element)
return Gitlab::MarkerRange::DELETION if element.removed?
return Gitlab::MarkerRange::ADDITION if element.added?
nil
end
end end
end end
end end
...@@ -31,7 +31,7 @@ module Gitlab ...@@ -31,7 +31,7 @@ module Gitlab
@chunks.add(segment) @chunks.add(segment)
when Segments::Newline when Segments::Newline
yielder << build_line(@chunks.content, nil, parent_file: diff_file) yielder << build_line(@chunks.content, nil, parent_file: diff_file).tap { |line| line.set_marker_ranges(@chunks.marker_ranges) }
@chunks.reset @chunks.reset
counter.increase_pos_num counter.increase_pos_num
......
...@@ -49,15 +49,15 @@ RSpec.describe Gitlab::Diff::CharDiff do ...@@ -49,15 +49,15 @@ RSpec.describe Gitlab::Diff::CharDiff do
old_diffs, new_diffs = subject old_diffs, new_diffs = subject
expect(old_diffs).to eq([]) expect(old_diffs).to eq([])
expect(new_diffs).to eq([0..12]) expect(new_diffs).to eq([Gitlab::MarkerRange.new(0, 12, mode: :addition)])
end end
end end
it 'returns ranges of changes' do it 'returns ranges of changes' do
old_diffs, new_diffs = subject old_diffs, new_diffs = subject
expect(old_diffs).to eq([11..11]) expect(old_diffs).to eq([Gitlab::MarkerRange.new(11, 11, mode: :deletion)])
expect(new_diffs).to eq([3..3]) expect(new_diffs).to eq([Gitlab::MarkerRange.new(3, 3, mode: :addition)])
end end
end end
......
...@@ -9,7 +9,7 @@ RSpec.describe Gitlab::MarkerRange do ...@@ -9,7 +9,7 @@ RSpec.describe Gitlab::MarkerRange do
let(:last) { 10 } let(:last) { 10 }
let(:mode) { nil } let(:mode) { nil }
it { is_expected.to eq(first..last) } it { expect(marker_range.to_range).to eq(first..last) }
it 'behaves like a Range' do it 'behaves like a Range' do
is_expected.to be_kind_of(Range) is_expected.to be_kind_of(Range)
...@@ -51,14 +51,14 @@ RSpec.describe Gitlab::MarkerRange do ...@@ -51,14 +51,14 @@ RSpec.describe Gitlab::MarkerRange do
end end
it 'keeps correct range' do it 'keeps correct range' do
is_expected.to eq(range) is_expected.to eq(described_class.new(1, 3))
end end
context 'when range excludes end' do context 'when range excludes end' do
let(:range) { 1...3 } let(:range) { 1...3 }
it 'keeps correct range' do it 'keeps correct range' do
is_expected.to eq(range) is_expected.to eq(described_class.new(1, 3, exclude_end: true))
end end
end end
...@@ -68,4 +68,31 @@ RSpec.describe Gitlab::MarkerRange do ...@@ -68,4 +68,31 @@ RSpec.describe Gitlab::MarkerRange do
it { is_expected.to be(marker_range) } it { is_expected.to be(marker_range) }
end end
end end
describe '#==' do
subject { default_marker_range == another_marker_range }
let(:default_marker_range) { described_class.new(0, 1, mode: :addition) }
let(:another_marker_range) { default_marker_range }
it { is_expected.to be_truthy }
context 'when marker ranges have different modes' do
let(:another_marker_range) { described_class.new(0, 1, mode: :deletion) }
it { is_expected.to be_falsey }
end
context 'when marker ranges have different ranges' do
let(:another_marker_range) { described_class.new(0, 2, mode: :addition) }
it { is_expected.to be_falsey }
end
context 'when marker ranges is a simple range' do
let(:another_marker_range) { (0..1) }
it { is_expected.to be_falsey }
end
end
end end
...@@ -41,4 +41,27 @@ RSpec.describe Gitlab::WordDiff::ChunkCollection do ...@@ -41,4 +41,27 @@ RSpec.describe Gitlab::WordDiff::ChunkCollection do
expect(collection.content).to eq('') expect(collection.content).to eq('')
end end
end end
describe '#marker_ranges' do
let(:chunks) do
[
Gitlab::WordDiff::Segments::Chunk.new(' Hello '),
Gitlab::WordDiff::Segments::Chunk.new('-World'),
Gitlab::WordDiff::Segments::Chunk.new('+GitLab'),
Gitlab::WordDiff::Segments::Chunk.new('+!!!')
]
end
it 'returns marker ranges for every chunk with changes' do
chunks.each { |chunk| collection.add(chunk) }
expect(collection.marker_ranges).to eq(
[
Gitlab::MarkerRange.new(6, 10, mode: :deletion),
Gitlab::MarkerRange.new(11, 16, mode: :addition),
Gitlab::MarkerRange.new(17, 19, mode: :addition)
]
)
end
end
end end
...@@ -36,15 +36,26 @@ RSpec.describe Gitlab::WordDiff::Parser do ...@@ -36,15 +36,26 @@ RSpec.describe Gitlab::WordDiff::Parser do
aggregate_failures do aggregate_failures do
expect(diff_lines.count).to eq(7) expect(diff_lines.count).to eq(7)
expect(diff_lines.map(&:to_hash)).to match_array( expect(diff_lines.map { |line| diff_line_attributes(line) }).to eq(
[ [
a_hash_including(index: 0, old_pos: 1, new_pos: 1, text: '', type: nil), { index: 0, old_pos: 1, new_pos: 1, text: '', type: nil, marker_ranges: [] },
a_hash_including(index: 1, old_pos: 2, new_pos: 2, text: 'Unchanged line', type: nil), { index: 1, old_pos: 2, new_pos: 2, text: 'Unchanged line', type: nil, marker_ranges: [] },
a_hash_including(index: 2, old_pos: 3, new_pos: 3, text: '', type: nil), { index: 2, old_pos: 3, new_pos: 3, text: '', type: nil, marker_ranges: [] },
a_hash_including(index: 3, old_pos: 4, new_pos: 4, text: 'Old changeNew addition unchanged content', type: nil), { index: 3, old_pos: 4, new_pos: 4, text: 'Old changeNew addition unchanged content', type: nil,
a_hash_including(index: 4, old_pos: 50, new_pos: 50, text: '@@ -50,14 +50,13 @@', type: 'match'), marker_ranges: [
a_hash_including(index: 5, old_pos: 50, new_pos: 50, text: 'First change same same same_removed_added_end of the line', type: nil), Gitlab::MarkerRange.new(0, 9, mode: :deletion),
a_hash_including(index: 6, old_pos: 51, new_pos: 51, text: '', type: nil) Gitlab::MarkerRange.new(10, 21, mode: :addition)
] },
{ index: 4, old_pos: 50, new_pos: 50, text: '@@ -50,14 +50,13 @@', type: 'match', marker_ranges: [] },
{ index: 5, old_pos: 50, new_pos: 50, text: 'First change same same same_removed_added_end of the line', type: nil,
marker_ranges: [
Gitlab::MarkerRange.new(0, 11, mode: :addition),
Gitlab::MarkerRange.new(28, 35, mode: :deletion),
Gitlab::MarkerRange.new(36, 41, mode: :addition)
] },
{ index: 6, old_pos: 51, new_pos: 51, text: '', type: nil, marker_ranges: [] }
] ]
) )
end end
...@@ -64,4 +75,17 @@ RSpec.describe Gitlab::WordDiff::Parser do ...@@ -64,4 +75,17 @@ RSpec.describe Gitlab::WordDiff::Parser do
it { is_expected.to eq([]) } it { is_expected.to eq([]) }
end end
end end
private
def diff_line_attributes(diff_line)
{
index: diff_line.index,
old_pos: diff_line.old_pos,
new_pos: diff_line.new_pos,
text: diff_line.text,
type: diff_line.type,
marker_ranges: diff_line.marker_ranges
}
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment