Commit 0988193e authored by Bob Van Landuyt's avatar Bob Van Landuyt

Merge branch 'eb-sort-code-quality-mr-widget' into 'master'

Sort code quality degradations in comparison reports

See merge request gitlab-org/gitlab!57258
parents 32f7cd15 c6845f9d
---
title: Sort code quality degradations in MR Widget comparison reports
merge_request: 57258
author:
type: added
...@@ -6,6 +6,7 @@ module Gitlab ...@@ -6,6 +6,7 @@ module Gitlab
class CodequalityReports class CodequalityReports
attr_reader :degradations, :error_message attr_reader :degradations, :error_message
SEVERITY_PRIORITIES = %w(blocker critical major minor info).map.with_index.to_h.freeze # { "blocker" => 0, "critical" => 1 ... }
CODECLIMATE_SCHEMA_PATH = Rails.root.join('app', 'validators', 'json_schemas', 'codeclimate.json').to_s CODECLIMATE_SCHEMA_PATH = Rails.root.join('app', 'validators', 'json_schemas', 'codeclimate.json').to_s
def initialize def initialize
...@@ -29,6 +30,12 @@ module Gitlab ...@@ -29,6 +30,12 @@ module Gitlab
@degradations.values @degradations.values
end end
def sort_degradations!
@degradations = @degradations.sort_by do |_fingerprint, degradation|
SEVERITY_PRIORITIES[degradation.dig(:severity)]
end.to_h
end
private private
def valid_degradation?(degradation) def valid_degradation?(degradation)
......
...@@ -7,6 +7,11 @@ module Gitlab ...@@ -7,6 +7,11 @@ module Gitlab
def initialize(base_report, head_report) def initialize(base_report, head_report)
@base_report = base_report @base_report = base_report
@head_report = head_report @head_report = head_report
unless not_found?
@base_report.sort_degradations!
@head_report.sort_degradations!
end
end end
def success? def success?
......
...@@ -95,4 +95,47 @@ FactoryBot.define do ...@@ -95,4 +95,47 @@ FactoryBot.define do
}.with_indifferent_access }.with_indifferent_access
end end
end end
# TODO: Use this in all other specs and remove the previous numbered factories
# https://gitlab.com/gitlab-org/gitlab/-/issues/325886
factory :codequality_degradation, class: Hash do
skip_create
# Feel free to add in more configurable properties here
# as the need arises
fingerprint { SecureRandom.hex }
severity { "major" }
Gitlab::Ci::Reports::CodequalityReports::SEVERITY_PRIORITIES.keys.each do |s|
trait s.to_sym do
severity { s }
end
end
initialize_with do
{
"categories": [
"Complexity"
],
"check_name": "argument_count",
"content": {
"body": ""
},
"description": "Avoid parameter lists longer than 5 parameters. [12/5]",
"fingerprint": fingerprint,
"location": {
"path": "file_a.rb",
"lines": {
"begin": 10,
"end": 10
}
},
"other_locations": [],
"remediation_points": 900000,
"severity": severity,
"type": "issue",
"engine_name": "structure"
}.with_indifferent_access
end
end
end end
...@@ -6,15 +6,17 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do ...@@ -6,15 +6,17 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do
let(:comparer) { described_class.new(base_report, head_report) } let(:comparer) { described_class.new(base_report, head_report) }
let(:base_report) { Gitlab::Ci::Reports::CodequalityReports.new } let(:base_report) { Gitlab::Ci::Reports::CodequalityReports.new }
let(:head_report) { Gitlab::Ci::Reports::CodequalityReports.new } let(:head_report) { Gitlab::Ci::Reports::CodequalityReports.new }
let(:degradation_1) { build(:codequality_degradation_1) } let(:major_degradation) { build(:codequality_degradation, :major) }
let(:degradation_2) { build(:codequality_degradation_2) } let(:minor_degradation) { build(:codequality_degradation, :major) }
let(:critical_degradation) { build(:codequality_degradation, :critical) }
let(:blocker_degradation) { build(:codequality_degradation, :blocker) }
describe '#status' do describe '#status' do
subject(:report_status) { comparer.status } subject(:report_status) { comparer.status }
context 'when head report has an error' do context 'when head report has an error' do
before do before do
head_report.add_degradation(degradation_1) head_report.add_degradation(major_degradation)
end end
it 'returns status failed' do it 'returns status failed' do
...@@ -50,7 +52,7 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do ...@@ -50,7 +52,7 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do
context 'when head report has an error' do context 'when head report has an error' do
before do before do
head_report.add_degradation(degradation_1) head_report.add_degradation(major_degradation)
end end
it 'returns the number of new errors' do it 'returns the number of new errors' do
...@@ -70,8 +72,8 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do ...@@ -70,8 +72,8 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do
context 'when base report has an error and head has a different error' do context 'when base report has an error and head has a different error' do
before do before do
base_report.add_degradation(degradation_1) base_report.add_degradation(major_degradation)
head_report.add_degradation(degradation_2) head_report.add_degradation(minor_degradation)
end end
it 'counts the base report error as resolved' do it 'counts the base report error as resolved' do
...@@ -81,7 +83,7 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do ...@@ -81,7 +83,7 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do
context 'when base report has errors head has no errors' do context 'when base report has errors head has no errors' do
before do before do
base_report.add_degradation(degradation_1) base_report.add_degradation(major_degradation)
end end
it 'counts the base report errors as resolved' do it 'counts the base report errors as resolved' do
...@@ -91,8 +93,8 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do ...@@ -91,8 +93,8 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do
context 'when base report has errors and head has the same error' do context 'when base report has errors and head has the same error' do
before do before do
base_report.add_degradation(degradation_1) base_report.add_degradation(major_degradation)
head_report.add_degradation(degradation_1) head_report.add_degradation(major_degradation)
end end
it 'returns zero' do it 'returns zero' do
...@@ -102,7 +104,7 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do ...@@ -102,7 +104,7 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do
context 'when base report does not have errors and head has errors' do context 'when base report does not have errors and head has errors' do
before do before do
head_report.add_degradation(degradation_1) head_report.add_degradation(major_degradation)
end end
it 'returns zero' do it 'returns zero' do
...@@ -124,7 +126,7 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do ...@@ -124,7 +126,7 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do
context 'when base report has an error' do context 'when base report has an error' do
before do before do
base_report.add_degradation(degradation_1) base_report.add_degradation(major_degradation)
end end
it 'returns zero' do it 'returns zero' do
...@@ -134,7 +136,7 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do ...@@ -134,7 +136,7 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do
context 'when head report has an error' do context 'when head report has an error' do
before do before do
head_report.add_degradation(degradation_1) head_report.add_degradation(major_degradation)
end end
it 'includes the head report error in the count' do it 'includes the head report error in the count' do
...@@ -144,8 +146,8 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do ...@@ -144,8 +146,8 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do
context 'when base report has errors and head report has errors' do context 'when base report has errors and head report has errors' do
before do before do
base_report.add_degradation(degradation_1) base_report.add_degradation(major_degradation)
head_report.add_degradation(degradation_2) head_report.add_degradation(minor_degradation)
end end
it 'includes errors in the count' do it 'includes errors in the count' do
...@@ -155,9 +157,9 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do ...@@ -155,9 +157,9 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do
context 'when base report has errors and head report has the same error' do context 'when base report has errors and head report has the same error' do
before do before do
base_report.add_degradation(degradation_1) base_report.add_degradation(major_degradation)
head_report.add_degradation(degradation_1) head_report.add_degradation(major_degradation)
head_report.add_degradation(degradation_2) head_report.add_degradation(minor_degradation)
end end
it 'includes errors in the count' do it 'includes errors in the count' do
...@@ -179,20 +181,28 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do ...@@ -179,20 +181,28 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do
context 'when base report has errors and head has the same error' do context 'when base report has errors and head has the same error' do
before do before do
base_report.add_degradation(degradation_1) base_report.add_degradation(major_degradation)
head_report.add_degradation(degradation_1) base_report.add_degradation(critical_degradation)
head_report.add_degradation(degradation_2) base_report.add_degradation(blocker_degradation)
end head_report.add_degradation(critical_degradation)
head_report.add_degradation(blocker_degradation)
it 'includes the base report errors' do head_report.add_degradation(major_degradation)
expect(existing_errors).to contain_exactly(degradation_1) head_report.add_degradation(minor_degradation)
end
it 'includes the base report errors sorted by severity' do
expect(existing_errors).to eq([
blocker_degradation,
critical_degradation,
major_degradation
])
end end
end end
context 'when base report has errors and head has a different error' do context 'when base report has errors and head has a different error' do
before do before do
base_report.add_degradation(degradation_1) base_report.add_degradation(major_degradation)
head_report.add_degradation(degradation_2) head_report.add_degradation(minor_degradation)
end end
it 'returns an empty array' do it 'returns an empty array' do
...@@ -202,7 +212,7 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do ...@@ -202,7 +212,7 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do
context 'when base report does not have errors and head has errors' do context 'when base report does not have errors and head has errors' do
before do before do
head_report.add_degradation(degradation_1) head_report.add_degradation(major_degradation)
end end
it 'returns an empty array' do it 'returns an empty array' do
...@@ -224,19 +234,25 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do ...@@ -224,19 +234,25 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do
context 'when base report has errors and head has more errors' do context 'when base report has errors and head has more errors' do
before do before do
base_report.add_degradation(degradation_1) base_report.add_degradation(major_degradation)
head_report.add_degradation(degradation_1) head_report.add_degradation(critical_degradation)
head_report.add_degradation(degradation_2) head_report.add_degradation(minor_degradation)
head_report.add_degradation(blocker_degradation)
head_report.add_degradation(major_degradation)
end end
it 'includes errors not found in the base report' do it 'includes errors not found in the base report sorted by severity' do
expect(new_errors).to eq([degradation_2]) expect(new_errors).to eq([
blocker_degradation,
critical_degradation,
minor_degradation
])
end end
end end
context 'when base report has an error and head has no errors' do context 'when base report has an error and head has no errors' do
before do before do
base_report.add_degradation(degradation_1) base_report.add_degradation(major_degradation)
end end
it 'returns an empty array' do it 'returns an empty array' do
...@@ -246,11 +262,11 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do ...@@ -246,11 +262,11 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do
context 'when base report does not have errors and head has errors' do context 'when base report does not have errors and head has errors' do
before do before do
head_report.add_degradation(degradation_1) head_report.add_degradation(major_degradation)
end end
it 'returns the head report error' do it 'returns the head report error' do
expect(new_errors).to eq([degradation_1]) expect(new_errors).to eq([major_degradation])
end end
end end
...@@ -268,9 +284,9 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do ...@@ -268,9 +284,9 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do
context 'when base report errors are still found in the head report' do context 'when base report errors are still found in the head report' do
before do before do
base_report.add_degradation(degradation_1) base_report.add_degradation(major_degradation)
head_report.add_degradation(degradation_1) head_report.add_degradation(major_degradation)
head_report.add_degradation(degradation_2) head_report.add_degradation(minor_degradation)
end end
it 'returns an empty array' do it 'returns an empty array' do
...@@ -280,18 +296,25 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do ...@@ -280,18 +296,25 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReportsComparer do
context 'when base report has errors and head has a different error' do context 'when base report has errors and head has a different error' do
before do before do
base_report.add_degradation(degradation_1) base_report.add_degradation(major_degradation)
head_report.add_degradation(degradation_2) base_report.add_degradation(minor_degradation)
base_report.add_degradation(critical_degradation)
base_report.add_degradation(blocker_degradation)
head_report.add_degradation(major_degradation)
end end
it 'returns the base report error' do it 'returns the base report errors not found in the head report, sorted by severity' do
expect(resolved_errors).to eq([degradation_1]) expect(resolved_errors).to eq([
blocker_degradation,
critical_degradation,
minor_degradation
])
end end
end end
context 'when base report does not have errors and head has errors' do context 'when base report does not have errors and head has errors' do
before do before do
head_report.add_degradation(degradation_1) head_report.add_degradation(major_degradation)
end end
it 'returns an empty array' do it 'returns an empty array' do
......
...@@ -77,4 +77,36 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReports do ...@@ -77,4 +77,36 @@ RSpec.describe Gitlab::Ci::Reports::CodequalityReports do
end end
end end
end end
describe '#sort_degradations!' do
let(:major) { build(:codequality_degradation, :major) }
let(:minor) { build(:codequality_degradation, :minor) }
let(:blocker) { build(:codequality_degradation, :blocker) }
let(:info) { build(:codequality_degradation, :info) }
let(:major_2) { build(:codequality_degradation, :major) }
let(:critical) { build(:codequality_degradation, :critical) }
let(:codequality_report) { described_class.new }
before do
codequality_report.add_degradation(major)
codequality_report.add_degradation(minor)
codequality_report.add_degradation(blocker)
codequality_report.add_degradation(major_2)
codequality_report.add_degradation(info)
codequality_report.add_degradation(critical)
codequality_report.sort_degradations!
end
it 'sorts degradations based on severity' do
expect(codequality_report.degradations.values).to eq([
blocker,
critical,
major,
major_2,
minor,
info
])
end
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