From 6f0b5800a92e5a0a9b94a36e013baa6361d638d5 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Mon, 8 Aug 2016 13:37:16 +0200 Subject: [PATCH 01/18] Add empty test coverage badge class and specs --- lib/gitlab/badge/coverage.rb | 17 +++++++++++++++++ spec/lib/gitlab/badge/coverage_spec.rb | 19 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 lib/gitlab/badge/coverage.rb create mode 100644 spec/lib/gitlab/badge/coverage_spec.rb diff --git a/lib/gitlab/badge/coverage.rb b/lib/gitlab/badge/coverage.rb new file mode 100644 index 00000000000..94af3a7ec34 --- /dev/null +++ b/lib/gitlab/badge/coverage.rb @@ -0,0 +1,17 @@ +module Gitlab + module Badge + ## + # Test coverage badge + # + class Coverage + def initialize(project, ref, job = nil) + @project = project + @ref = ref + @job = job + end + + def coverage + end + end + end +end diff --git a/spec/lib/gitlab/badge/coverage_spec.rb b/spec/lib/gitlab/badge/coverage_spec.rb new file mode 100644 index 00000000000..343ca3c0f85 --- /dev/null +++ b/spec/lib/gitlab/badge/coverage_spec.rb @@ -0,0 +1,19 @@ +require 'spec_helper' + +describe Gitlab::Badge::Coverage do + let(:project) { create(:project) } + + let(:pipeline) do + create(:ci_pipeline, project: project, + sha: project.commit.id, + ref: 'master') + end + + let(:badge) { described_class.new(project, 'master') } + + context 'builds exist' do + end + + context 'build does not exist' do + end +end From 9f0b46c05aef9d0352bfaa5e42e34143227de8ff Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Wed, 10 Aug 2016 14:12:31 +0200 Subject: [PATCH 02/18] Move badges to separate modules and add base class --- app/controllers/projects/badges_controller.rb | 2 +- .../projects/pipelines_settings_controller.rb | 2 +- lib/gitlab/badge/base.rb | 21 ++++++++++++ lib/gitlab/badge/build.rb | 30 ----------------- lib/gitlab/badge/build/metadata.rb | 2 +- lib/gitlab/badge/build/status.rb | 32 +++++++++++++++++++ lib/gitlab/badge/build/template.rb | 2 +- lib/gitlab/badge/coverage.rb | 17 ---------- lib/gitlab/badge/coverage/report.rb | 19 +++++++++++ .../{build_spec.rb => build/status_spec.rb} | 2 +- .../report_spec.rb} | 8 +++-- 11 files changed, 82 insertions(+), 55 deletions(-) create mode 100644 lib/gitlab/badge/base.rb delete mode 100644 lib/gitlab/badge/build.rb create mode 100644 lib/gitlab/badge/build/status.rb delete mode 100644 lib/gitlab/badge/coverage.rb create mode 100644 lib/gitlab/badge/coverage/report.rb rename spec/lib/gitlab/badge/{build_spec.rb => build/status_spec.rb} (98%) rename spec/lib/gitlab/badge/{coverage_spec.rb => coverage/report_spec.rb} (64%) diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb index d0f5071d2cc..e026ceaf757 100644 --- a/app/controllers/projects/badges_controller.rb +++ b/app/controllers/projects/badges_controller.rb @@ -4,7 +4,7 @@ class Projects::BadgesController < Projects::ApplicationController before_action :no_cache_headers, except: [:index] def build - badge = Gitlab::Badge::Build.new(project, params[:ref]) + badge = Gitlab::Badge::Build::Status.new(project, params[:ref]) respond_to do |format| format.html { render_404 } diff --git a/app/controllers/projects/pipelines_settings_controller.rb b/app/controllers/projects/pipelines_settings_controller.rb index 75dd3648e45..fe7cb748f43 100644 --- a/app/controllers/projects/pipelines_settings_controller.rb +++ b/app/controllers/projects/pipelines_settings_controller.rb @@ -3,7 +3,7 @@ class Projects::PipelinesSettingsController < Projects::ApplicationController def show @ref = params[:ref] || @project.default_branch || 'master' - @build_badge = Gitlab::Badge::Build.new(@project, @ref).metadata + @build_badge = Gitlab::Badge::Build::Status.new(@project, @ref).metadata end def update diff --git a/lib/gitlab/badge/base.rb b/lib/gitlab/badge/base.rb new file mode 100644 index 00000000000..229e7b5aa57 --- /dev/null +++ b/lib/gitlab/badge/base.rb @@ -0,0 +1,21 @@ +module Gitlab + module Badge + class Base + def key_text + raise NotImplementedError + end + + def value_text + raise NotImplementedError + end + + def metadata + raise NotImplementedError + end + + def template + raise NotImplementedError + end + end + end +end diff --git a/lib/gitlab/badge/build.rb b/lib/gitlab/badge/build.rb deleted file mode 100644 index 1de721a2269..00000000000 --- a/lib/gitlab/badge/build.rb +++ /dev/null @@ -1,30 +0,0 @@ -module Gitlab - module Badge - ## - # Build badge - # - class Build - delegate :key_text, :value_text, to: :template - - def initialize(project, ref) - @project = project - @ref = ref - @sha = @project.commit(@ref).try(:sha) - end - - def status - @project.pipelines - .where(sha: @sha, ref: @ref) - .status || 'unknown' - end - - def metadata - @metadata ||= Build::Metadata.new(@project, @ref) - end - - def template - @template ||= Build::Template.new(status) - end - end - end -end diff --git a/lib/gitlab/badge/build/metadata.rb b/lib/gitlab/badge/build/metadata.rb index 553ef8d7b16..fbe10b948c4 100644 --- a/lib/gitlab/badge/build/metadata.rb +++ b/lib/gitlab/badge/build/metadata.rb @@ -1,6 +1,6 @@ module Gitlab module Badge - class Build + module Build ## # Class that describes build badge metadata # diff --git a/lib/gitlab/badge/build/status.rb b/lib/gitlab/badge/build/status.rb new file mode 100644 index 00000000000..a72e284d513 --- /dev/null +++ b/lib/gitlab/badge/build/status.rb @@ -0,0 +1,32 @@ +module Gitlab + module Badge + module Build + ## + # Build status badge + # + class Status < Badge::Base + delegate :key_text, :value_text, to: :template + + def initialize(project, ref) + @project = project + @ref = ref + @sha = @project.commit(@ref).try(:sha) + end + + def status + @project.pipelines + .where(sha: @sha, ref: @ref) + .status || 'unknown' + end + + def metadata + @metadata ||= Build::Metadata.new(@project, @ref) + end + + def template + @template ||= Build::Template.new(status) + end + end + end + end +end diff --git a/lib/gitlab/badge/build/template.rb b/lib/gitlab/badge/build/template.rb index deba3b669b3..779569d0cd7 100644 --- a/lib/gitlab/badge/build/template.rb +++ b/lib/gitlab/badge/build/template.rb @@ -1,6 +1,6 @@ module Gitlab module Badge - class Build + module Build ## # Class that represents a build badge template. # diff --git a/lib/gitlab/badge/coverage.rb b/lib/gitlab/badge/coverage.rb deleted file mode 100644 index 94af3a7ec34..00000000000 --- a/lib/gitlab/badge/coverage.rb +++ /dev/null @@ -1,17 +0,0 @@ -module Gitlab - module Badge - ## - # Test coverage badge - # - class Coverage - def initialize(project, ref, job = nil) - @project = project - @ref = ref - @job = job - end - - def coverage - end - end - end -end diff --git a/lib/gitlab/badge/coverage/report.rb b/lib/gitlab/badge/coverage/report.rb new file mode 100644 index 00000000000..e6de15e085f --- /dev/null +++ b/lib/gitlab/badge/coverage/report.rb @@ -0,0 +1,19 @@ +module Gitlab + module Badge + module Coverage + ## + # Test coverage report badge + # + class Report < Badge::Base + def initialize(project, ref, job = nil) + @project = project + @ref = ref + @job = job + end + + def coverage + end + end + end + end +end diff --git a/spec/lib/gitlab/badge/build_spec.rb b/spec/lib/gitlab/badge/build/status_spec.rb similarity index 98% rename from spec/lib/gitlab/badge/build_spec.rb rename to spec/lib/gitlab/badge/build/status_spec.rb index bb8144d5122..fa5bc068918 100644 --- a/spec/lib/gitlab/badge/build_spec.rb +++ b/spec/lib/gitlab/badge/build/status_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::Badge::Build do +describe Gitlab::Badge::Build::Status do let(:project) { create(:project) } let(:sha) { project.commit.sha } let(:branch) { 'master' } diff --git a/spec/lib/gitlab/badge/coverage_spec.rb b/spec/lib/gitlab/badge/coverage/report_spec.rb similarity index 64% rename from spec/lib/gitlab/badge/coverage_spec.rb rename to spec/lib/gitlab/badge/coverage/report_spec.rb index 343ca3c0f85..57b89dd8cda 100644 --- a/spec/lib/gitlab/badge/coverage_spec.rb +++ b/spec/lib/gitlab/badge/coverage/report_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::Badge::Coverage do +describe Gitlab::Badge::Coverage::Report do let(:project) { create(:project) } let(:pipeline) do @@ -9,11 +9,13 @@ describe Gitlab::Badge::Coverage do ref: 'master') end - let(:badge) { described_class.new(project, 'master') } + let(:badge) do + described_class.new(project, 'master') + end context 'builds exist' do end - context 'build does not exist' do + context 'builds do not exist' do end end From f3de46e6b0d4cc61e00c884753a8c9eec66f66c4 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Thu, 11 Aug 2016 11:16:14 +0200 Subject: [PATCH 03/18] Refactor badge template and metadata classes --- lib/gitlab/badge/base.rb | 4 +-- lib/gitlab/badge/build/metadata.rb | 6 ++-- lib/gitlab/badge/build/status.rb | 11 ++++-- lib/gitlab/badge/build/template.rb | 12 +++---- spec/lib/gitlab/badge/build/metadata_spec.rb | 25 +++++++------- spec/lib/gitlab/badge/build/status_spec.rb | 36 +++++++------------- spec/lib/gitlab/badge/build/template_spec.rb | 22 +++++++----- 7 files changed, 58 insertions(+), 58 deletions(-) diff --git a/lib/gitlab/badge/base.rb b/lib/gitlab/badge/base.rb index 229e7b5aa57..909fa24fa90 100644 --- a/lib/gitlab/badge/base.rb +++ b/lib/gitlab/badge/base.rb @@ -1,11 +1,11 @@ module Gitlab module Badge class Base - def key_text + def entity raise NotImplementedError end - def value_text + def status raise NotImplementedError end diff --git a/lib/gitlab/badge/build/metadata.rb b/lib/gitlab/badge/build/metadata.rb index fbe10b948c4..52a10b19298 100644 --- a/lib/gitlab/badge/build/metadata.rb +++ b/lib/gitlab/badge/build/metadata.rb @@ -9,9 +9,9 @@ module Gitlab include ActionView::Helpers::AssetTagHelper include ActionView::Helpers::UrlHelper - def initialize(project, ref) - @project = project - @ref = ref + def initialize(badge) + @project = badge.project + @ref = badge.ref end def to_html diff --git a/lib/gitlab/badge/build/status.rb b/lib/gitlab/badge/build/status.rb index a72e284d513..50aa45e5406 100644 --- a/lib/gitlab/badge/build/status.rb +++ b/lib/gitlab/badge/build/status.rb @@ -5,14 +5,19 @@ module Gitlab # Build status badge # class Status < Badge::Base - delegate :key_text, :value_text, to: :template + attr_reader :project, :ref def initialize(project, ref) @project = project @ref = ref + @sha = @project.commit(@ref).try(:sha) end + def entity + 'build' + end + def status @project.pipelines .where(sha: @sha, ref: @ref) @@ -20,11 +25,11 @@ module Gitlab end def metadata - @metadata ||= Build::Metadata.new(@project, @ref) + @metadata ||= Build::Metadata.new(self) end def template - @template ||= Build::Template.new(status) + @template ||= Build::Template.new(self) end end end diff --git a/lib/gitlab/badge/build/template.rb b/lib/gitlab/badge/build/template.rb index 779569d0cd7..f52589ff736 100644 --- a/lib/gitlab/badge/build/template.rb +++ b/lib/gitlab/badge/build/template.rb @@ -17,16 +17,17 @@ module Gitlab unknown: '#9f9f9f' } - def initialize(status) - @status = status + def initialize(badge) + @entity = badge.entity + @status = badge.status end def key_text - 'build' + @entity.to_s end def value_text - @status + @status.to_s end def key_width @@ -42,8 +43,7 @@ module Gitlab end def value_color - STATUS_COLOR[@status.to_sym] || - STATUS_COLOR[:unknown] + STATUS_COLOR[@status.to_sym] || STATUS_COLOR[:unknown] end def key_text_anchor diff --git a/spec/lib/gitlab/badge/build/metadata_spec.rb b/spec/lib/gitlab/badge/build/metadata_spec.rb index ad5388215c2..4044a82d16c 100644 --- a/spec/lib/gitlab/badge/build/metadata_spec.rb +++ b/spec/lib/gitlab/badge/build/metadata_spec.rb @@ -1,16 +1,15 @@ require 'spec_helper' describe Gitlab::Badge::Build::Metadata do - let(:project) { create(:project) } - let(:branch) { 'master' } - let(:badge) { described_class.new(project, branch) } + let(:badge) { double(project: create(:project), ref: 'feature') } + let(:metadata) { described_class.new(badge) } describe '#to_html' do - let(:html) { Nokogiri::HTML.parse(badge.to_html) } + let(:html) { Nokogiri::HTML.parse(metadata.to_html) } let(:a_href) { html.at('a') } it 'points to link' do - expect(a_href[:href]).to eq badge.link_url + expect(a_href[:href]).to eq metadata.link_url end it 'contains clickable image' do @@ -19,19 +18,21 @@ describe Gitlab::Badge::Build::Metadata do end describe '#to_markdown' do - subject { badge.to_markdown } + subject { metadata.to_markdown } - it { is_expected.to include badge.image_url } - it { is_expected.to include badge.link_url } + it { is_expected.to include metadata.image_url } + it { is_expected.to include metadata.link_url } end describe '#image_url' do - subject { badge.image_url } - it { is_expected.to include "badges/#{branch}/build.svg" } + it 'returns valid url' do + expect(metadata.image_url).to include 'badges/feature/build.svg' + end end describe '#link_url' do - subject { badge.link_url } - it { is_expected.to include "commits/#{branch}" } + it 'returns valid link' do + expect(metadata.link_url).to include 'commits/feature' + end end end diff --git a/spec/lib/gitlab/badge/build/status_spec.rb b/spec/lib/gitlab/badge/build/status_spec.rb index fa5bc068918..38eebb2a176 100644 --- a/spec/lib/gitlab/badge/build/status_spec.rb +++ b/spec/lib/gitlab/badge/build/status_spec.rb @@ -6,6 +6,18 @@ describe Gitlab::Badge::Build::Status do let(:branch) { 'master' } let(:badge) { described_class.new(project, branch) } + describe '#entity' do + it 'always says build' do + expect(badge.entity).to eq 'build' + end + end + + describe '#template' do + it 'returns badge template' do + expect(badge.template.key_text).to eq 'build' + end + end + describe '#metadata' do it 'returns badge metadata' do expect(badge.metadata.image_url) @@ -13,12 +25,6 @@ describe Gitlab::Badge::Build::Status do end end - describe '#key_text' do - it 'always says build' do - expect(badge.key_text).to eq 'build' - end - end - context 'build exists' do let!(:build) { create_build(project, sha, branch) } @@ -30,12 +36,6 @@ describe Gitlab::Badge::Build::Status do expect(badge.status).to eq 'success' end end - - describe '#value_text' do - it 'returns correct value text' do - expect(badge.value_text).to eq 'success' - end - end end context 'build failed' do @@ -46,12 +46,6 @@ describe Gitlab::Badge::Build::Status do expect(badge.status).to eq 'failed' end end - - describe '#value_text' do - it 'has correct value text' do - expect(badge.value_text).to eq 'failed' - end - end end context 'when outdated pipeline for given ref exists' do @@ -87,12 +81,6 @@ describe Gitlab::Badge::Build::Status do expect(badge.status).to eq 'unknown' end end - - describe '#value_text' do - it 'has correct value text' do - expect(badge.value_text).to eq 'unknown' - end - end end def create_build(project, sha, branch) diff --git a/spec/lib/gitlab/badge/build/template_spec.rb b/spec/lib/gitlab/badge/build/template_spec.rb index 86dead3c54e..a7e21fb8bb1 100644 --- a/spec/lib/gitlab/badge/build/template_spec.rb +++ b/spec/lib/gitlab/badge/build/template_spec.rb @@ -1,8 +1,8 @@ require 'spec_helper' describe Gitlab::Badge::Build::Template do - let(:status) { 'success' } - let(:template) { described_class.new(status) } + let(:badge) { double(entity: 'build', status: 'success') } + let(:template) { described_class.new(badge) } describe '#key_text' do it 'is always says build' do @@ -34,15 +34,15 @@ describe Gitlab::Badge::Build::Template do describe '#value_color' do context 'when status is success' do - let(:status) { 'success' } - it 'has expected color' do expect(template.value_color).to eq '#4c1' end end context 'when status is failed' do - let(:status) { 'failed' } + before do + allow(badge).to receive(:status).and_return('failed') + end it 'has expected color' do expect(template.value_color).to eq '#e05d44' @@ -50,7 +50,9 @@ describe Gitlab::Badge::Build::Template do end context 'when status is running' do - let(:status) { 'running' } + before do + allow(badge).to receive(:status).and_return('running') + end it 'has expected color' do expect(template.value_color).to eq '#dfb317' @@ -58,7 +60,9 @@ describe Gitlab::Badge::Build::Template do end context 'when status is unknown' do - let(:status) { 'unknown' } + before do + allow(badge).to receive(:status).and_return('unknown') + end it 'has expected color' do expect(template.value_color).to eq '#9f9f9f' @@ -66,7 +70,9 @@ describe Gitlab::Badge::Build::Template do end context 'when status does not match any known statuses' do - let(:status) { 'invalid status' } + before do + allow(badge).to receive(:status).and_return('invalid') + end it 'has expected color' do expect(template.value_color).to eq '#9f9f9f' From f0ff1bfdcc43decd1888f7b8d4a9e8c4dd5540d9 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Thu, 11 Aug 2016 12:38:03 +0200 Subject: [PATCH 04/18] Implement the main class of test coverage badge --- lib/gitlab/badge/coverage/report.rb | 31 +++++++- spec/lib/gitlab/badge/coverage/report_spec.rb | 78 ++++++++++++++++--- 2 files changed, 99 insertions(+), 10 deletions(-) diff --git a/lib/gitlab/badge/coverage/report.rb b/lib/gitlab/badge/coverage/report.rb index e6de15e085f..f06142003e3 100644 --- a/lib/gitlab/badge/coverage/report.rb +++ b/lib/gitlab/badge/coverage/report.rb @@ -5,13 +5,42 @@ module Gitlab # Test coverage report badge # class Report < Badge::Base + attr_reader :project, :ref, :job + def initialize(project, ref, job = nil) @project = project @ref = ref @job = job + + @pipeline = @project.pipelines + .where(ref: @ref) + .where(sha: @project.commit(@ref).try(:sha)) + .first end - def coverage + def entity + 'coverage' + end + + def status + @coverage ||= raw_coverage + return unless @coverage + + @coverage.to_i + end + + private + + def raw_coverage + return unless @pipeline + + if @job.blank? + @pipeline.coverage + else + @pipeline.builds + .find_by(name: @job) + .try(:coverage) + end end end end diff --git a/spec/lib/gitlab/badge/coverage/report_spec.rb b/spec/lib/gitlab/badge/coverage/report_spec.rb index 57b89dd8cda..46b14873ee9 100644 --- a/spec/lib/gitlab/badge/coverage/report_spec.rb +++ b/spec/lib/gitlab/badge/coverage/report_spec.rb @@ -2,20 +2,80 @@ require 'spec_helper' describe Gitlab::Badge::Coverage::Report do let(:project) { create(:project) } - - let(:pipeline) do - create(:ci_pipeline, project: project, - sha: project.commit.id, - ref: 'master') - end + let(:job_name) { nil } let(:badge) do - described_class.new(project, 'master') + described_class.new(project, 'master', job_name) end - context 'builds exist' do + describe '#entity' do + it 'describes a coverage' do + expect(badge.entity).to eq 'coverage' + end end - context 'builds do not exist' do + shared_examples 'unknown coverage report' do + context 'particular job specified' do + let(:job_name) { '' } + + it 'returns nil' do + expect(badge.status).to be_nil + end + end + + context 'particular job not specified' do + let(:job_name) { nil } + + it 'returns nil' do + expect(badge.status).to be_nil + end + end + end + + context 'pipeline exists' do + let!(:pipeline) do + create(:ci_pipeline, project: project, + sha: project.commit.id, + ref: 'master') + end + + context 'builds exist' do + before do + create(:ci_build, name: 'first', pipeline: pipeline, coverage: 40) + create(:ci_build, pipeline: pipeline, coverage: 60) + end + + context 'particular job specified' do + let(:job_name) { 'first' } + + it 'returns coverage for the particular job' do + expect(badge.status).to eq 40 + end + end + + context 'particular job not specified' do + let(:job_name) { '' } + + it 'returns arithemetic mean for the pipeline' do + expect(badge.status).to eq 50 + end + end + end + + context 'builds do not exist' do + it_behaves_like 'unknown coverage report' + + context 'particular job specified' do + let(:job_name) { 'nonexistent' } + + it 'retruns nil' do + expect(badge.status).to be_nil + end + end + end + end + + context 'pipeline does not exist' do + it_behaves_like 'unknown coverage report' end end From cdb0caaf320a67f193a7ab9faac9271a625d8b98 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Thu, 11 Aug 2016 13:56:20 +0200 Subject: [PATCH 05/18] Extract common badge metadata test examples --- spec/lib/gitlab/badge/build/metadata_spec.rb | 21 ++------------------ spec/lib/gitlab/badge/shared/metadata.rb | 21 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 19 deletions(-) create mode 100644 spec/lib/gitlab/badge/shared/metadata.rb diff --git a/spec/lib/gitlab/badge/build/metadata_spec.rb b/spec/lib/gitlab/badge/build/metadata_spec.rb index 4044a82d16c..d9354458707 100644 --- a/spec/lib/gitlab/badge/build/metadata_spec.rb +++ b/spec/lib/gitlab/badge/build/metadata_spec.rb @@ -1,28 +1,11 @@ require 'spec_helper' +require 'lib/gitlab/badge/shared/metadata' describe Gitlab::Badge::Build::Metadata do let(:badge) { double(project: create(:project), ref: 'feature') } let(:metadata) { described_class.new(badge) } - describe '#to_html' do - let(:html) { Nokogiri::HTML.parse(metadata.to_html) } - let(:a_href) { html.at('a') } - - it 'points to link' do - expect(a_href[:href]).to eq metadata.link_url - end - - it 'contains clickable image' do - expect(a_href.children.first.name).to eq 'img' - end - end - - describe '#to_markdown' do - subject { metadata.to_markdown } - - it { is_expected.to include metadata.image_url } - it { is_expected.to include metadata.link_url } - end + it_behaves_like 'badge metadata' describe '#image_url' do it 'returns valid url' do diff --git a/spec/lib/gitlab/badge/shared/metadata.rb b/spec/lib/gitlab/badge/shared/metadata.rb new file mode 100644 index 00000000000..0cf18514251 --- /dev/null +++ b/spec/lib/gitlab/badge/shared/metadata.rb @@ -0,0 +1,21 @@ +shared_examples 'badge metadata' do + describe '#to_html' do + let(:html) { Nokogiri::HTML.parse(metadata.to_html) } + let(:a_href) { html.at('a') } + + it 'points to link' do + expect(a_href[:href]).to eq metadata.link_url + end + + it 'contains clickable image' do + expect(a_href.children.first.name).to eq 'img' + end + end + + describe '#to_markdown' do + subject { metadata.to_markdown } + + it { is_expected.to include metadata.image_url } + it { is_expected.to include metadata.link_url } + end +end From 7b840c8483e2fe17a6c04474323cfb57c3c8a7d3 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Thu, 11 Aug 2016 13:58:57 +0200 Subject: [PATCH 06/18] Add coverage report badge metadata class --- config/routes.rb | 5 ++- lib/gitlab/badge/coverage/metadata.rb | 38 +++++++++++++++++++ .../gitlab/badge/coverage/metadata_spec.rb | 24 ++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 lib/gitlab/badge/coverage/metadata.rb create mode 100644 spec/lib/gitlab/badge/coverage/metadata_spec.rb diff --git a/config/routes.rb b/config/routes.rb index 9a98fab15a3..cf6773917cf 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -869,7 +869,10 @@ Rails.application.routes.draw do resources :badges, only: [:index] do collection do scope '*ref', constraints: { ref: Gitlab::Regex.git_reference_regex } do - get :build, constraints: { format: /svg/ } + constraints format: /svg/ do + get :build + get :coverage + end end end end diff --git a/lib/gitlab/badge/coverage/metadata.rb b/lib/gitlab/badge/coverage/metadata.rb new file mode 100644 index 00000000000..ae9e5e84051 --- /dev/null +++ b/lib/gitlab/badge/coverage/metadata.rb @@ -0,0 +1,38 @@ +module Gitlab + module Badge + module Coverage + ## + # Class that describes coverage badge metadata + # + class Metadata + include Gitlab::Application.routes.url_helpers + include ActionView::Helpers::AssetTagHelper + include ActionView::Helpers::UrlHelper + + def initialize(badge) + @project = badge.project + @ref = badge.ref + @job = badge.job + end + + def to_html + link_to(image_tag(image_url, alt: 'coverage report'), link_url) + end + + def to_markdown + "[![coverage report](#{image_url})](#{link_url})" + end + + def image_url + coverage_namespace_project_badges_url(@project.namespace, + @project, @ref, + format: :svg) + end + + def link_url + namespace_project_commits_url(@project.namespace, @project, id: @ref) + end + end + end + end +end diff --git a/spec/lib/gitlab/badge/coverage/metadata_spec.rb b/spec/lib/gitlab/badge/coverage/metadata_spec.rb new file mode 100644 index 00000000000..995b1a329ba --- /dev/null +++ b/spec/lib/gitlab/badge/coverage/metadata_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' +require 'lib/gitlab/badge/shared/metadata' + +describe Gitlab::Badge::Coverage::Metadata do + let(:badge) do + double(project: create(:project), ref: 'feature', job: 'test') + end + + let(:metadata) { described_class.new(badge) } + + it_behaves_like 'badge metadata' + + describe '#image_url' do + it 'returns valid url' do + expect(metadata.image_url).to include 'badges/feature/coverage.svg' + end + end + + describe '#link_url' do + it 'returns valid link' do + expect(metadata.link_url).to include 'commits/feature' + end + end +end From cc244160c5e2ecda2818348cb6b909f1dcb96e44 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Thu, 11 Aug 2016 14:08:27 +0200 Subject: [PATCH 07/18] Extract the abstract base class of badge metadata --- lib/gitlab/badge/build/metadata.rb | 14 ++------ lib/gitlab/badge/coverage/metadata.rb | 14 ++------ lib/gitlab/badge/metadata.rb | 36 +++++++++++++++++++ spec/lib/gitlab/badge/build/metadata_spec.rb | 6 ++++ .../gitlab/badge/coverage/metadata_spec.rb | 6 ++++ 5 files changed, 54 insertions(+), 22 deletions(-) create mode 100644 lib/gitlab/badge/metadata.rb diff --git a/lib/gitlab/badge/build/metadata.rb b/lib/gitlab/badge/build/metadata.rb index 52a10b19298..f87a7b7942e 100644 --- a/lib/gitlab/badge/build/metadata.rb +++ b/lib/gitlab/badge/build/metadata.rb @@ -4,22 +4,14 @@ module Gitlab ## # Class that describes build badge metadata # - class Metadata - include Gitlab::Application.routes.url_helpers - include ActionView::Helpers::AssetTagHelper - include ActionView::Helpers::UrlHelper - + class Metadata < Badge::Metadata def initialize(badge) @project = badge.project @ref = badge.ref end - def to_html - link_to(image_tag(image_url, alt: 'build status'), link_url) - end - - def to_markdown - "[![build status](#{image_url})](#{link_url})" + def title + 'build status' end def image_url diff --git a/lib/gitlab/badge/coverage/metadata.rb b/lib/gitlab/badge/coverage/metadata.rb index ae9e5e84051..53588185622 100644 --- a/lib/gitlab/badge/coverage/metadata.rb +++ b/lib/gitlab/badge/coverage/metadata.rb @@ -4,23 +4,15 @@ module Gitlab ## # Class that describes coverage badge metadata # - class Metadata - include Gitlab::Application.routes.url_helpers - include ActionView::Helpers::AssetTagHelper - include ActionView::Helpers::UrlHelper - + class Metadata < Badge::Metadata def initialize(badge) @project = badge.project @ref = badge.ref @job = badge.job end - def to_html - link_to(image_tag(image_url, alt: 'coverage report'), link_url) - end - - def to_markdown - "[![coverage report](#{image_url})](#{link_url})" + def title + 'coverage report' end def image_url diff --git a/lib/gitlab/badge/metadata.rb b/lib/gitlab/badge/metadata.rb new file mode 100644 index 00000000000..548f85b78bb --- /dev/null +++ b/lib/gitlab/badge/metadata.rb @@ -0,0 +1,36 @@ +module Gitlab + module Badge + ## + # Abstract class for badge metadata + # + class Metadata + include Gitlab::Application.routes.url_helpers + include ActionView::Helpers::AssetTagHelper + include ActionView::Helpers::UrlHelper + + def initialize(badge) + @badge = badge + end + + def to_html + link_to(image_tag(image_url, alt: title), link_url) + end + + def to_markdown + "[![#{title}](#{image_url})](#{link_url})" + end + + def title + raise NotImplementedError + end + + def image_url + raise NotImplementedError + end + + def link_url + raise NotImplementedError + end + end + end +end diff --git a/spec/lib/gitlab/badge/build/metadata_spec.rb b/spec/lib/gitlab/badge/build/metadata_spec.rb index d9354458707..d678e522721 100644 --- a/spec/lib/gitlab/badge/build/metadata_spec.rb +++ b/spec/lib/gitlab/badge/build/metadata_spec.rb @@ -7,6 +7,12 @@ describe Gitlab::Badge::Build::Metadata do it_behaves_like 'badge metadata' + describe '#title' do + it 'returns build status title' do + expect(metadata.title).to eq 'build status' + end + end + describe '#image_url' do it 'returns valid url' do expect(metadata.image_url).to include 'badges/feature/build.svg' diff --git a/spec/lib/gitlab/badge/coverage/metadata_spec.rb b/spec/lib/gitlab/badge/coverage/metadata_spec.rb index 995b1a329ba..74eaf7eaf8b 100644 --- a/spec/lib/gitlab/badge/coverage/metadata_spec.rb +++ b/spec/lib/gitlab/badge/coverage/metadata_spec.rb @@ -10,6 +10,12 @@ describe Gitlab::Badge::Coverage::Metadata do it_behaves_like 'badge metadata' + describe '#title' do + it 'returns coverage report title' do + expect(metadata.title).to eq 'coverage report' + end + end + describe '#image_url' do it 'returns valid url' do expect(metadata.image_url).to include 'badges/feature/coverage.svg' From 796efcc704558119c1e5cb298d45a4f592662cb7 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Thu, 11 Aug 2016 14:46:47 +0200 Subject: [PATCH 08/18] Add template class for coverage report badge --- lib/gitlab/badge/coverage/template.rb | 69 ++++++++++ .../gitlab/badge/coverage/template_spec.rb | 130 ++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 lib/gitlab/badge/coverage/template.rb create mode 100644 spec/lib/gitlab/badge/coverage/template_spec.rb diff --git a/lib/gitlab/badge/coverage/template.rb b/lib/gitlab/badge/coverage/template.rb new file mode 100644 index 00000000000..6f9a38b07dc --- /dev/null +++ b/lib/gitlab/badge/coverage/template.rb @@ -0,0 +1,69 @@ +module Gitlab + module Badge + module Coverage + ## + # Class that represents a coverage badge template. + # + # Template object will be passed to badge.svg.erb template. + # + class Template + STATUS_COLOR = { + good: '#4c1', + acceptable: '#b0c', + medium: '#dfb317', + low: '#e05d44', + unknown: '#9f9f9f' + } + + def initialize(badge) + @entity = badge.entity + @status = badge.status + end + + def key_text + @entity.to_s + end + + def value_text + @status ? "#{@status}%" : 'unknown' + end + + def key_width + 62 + end + + def value_width + @status ? 32 : 58 + end + + def key_color + '#555' + end + + def value_color + case @status + when nil then STATUS_COLOR[:unknown] + when 95..100 then STATUS_COLOR[:good] + when 90..95 then STATUS_COLOR[:acceptable] + when 75..90 then STATUS_COLOR[:medium] + when 0..75 then STATUS_COLOR[:low] + else + STATUS_COLOR[:unknown] + end + end + + def key_text_anchor + key_width / 2 + end + + def value_text_anchor + key_width + (value_width / 2) + end + + def width + key_width + value_width + end + end + end + end +end diff --git a/spec/lib/gitlab/badge/coverage/template_spec.rb b/spec/lib/gitlab/badge/coverage/template_spec.rb new file mode 100644 index 00000000000..a45de1dc677 --- /dev/null +++ b/spec/lib/gitlab/badge/coverage/template_spec.rb @@ -0,0 +1,130 @@ +require 'spec_helper' + +describe Gitlab::Badge::Coverage::Template do + let(:badge) { double(entity: 'coverage', status: 90) } + let(:template) { described_class.new(badge) } + + describe '#key_text' do + it 'is always says coverage' do + expect(template.key_text).to eq 'coverage' + end + end + + describe '#value_text' do + context 'when coverage is known' do + it 'returns coverage percentage' do + expect(template.value_text).to eq '90%' + end + end + + context 'when coverage is unknown' do + before do + allow(badge).to receive(:status).and_return(nil) + end + + it 'returns string that says coverage is unknown' do + expect(template.value_text).to eq 'unknown' + end + end + end + + describe '#key_width' do + it 'has a fixed key width' do + expect(template.key_width).to eq 62 + end + end + + describe '#value_width' do + context 'when coverage is known' do + it 'is narrower when coverage is known' do + expect(template.value_width).to eq 32 + end + end + + context 'when coverage is unknown' do + before do + allow(badge).to receive(:status).and_return(nil) + end + + it 'is wider when coverage is unknown to fit text' do + expect(template.value_width).to eq 58 + end + end + end + + describe '#key_color' do + it 'always has the same color' do + expect(template.key_color).to eq '#555' + end + end + + describe '#value_color' do + context 'when coverage is good' do + before do + allow(badge).to receive(:status).and_return(98) + end + + it 'is green' do + expect(template.value_color).to eq '#4c1' + end + end + + context 'when coverage is acceptable' do + before do + allow(badge).to receive(:status).and_return(90) + end + + it 'is green-orange' do + expect(template.value_color).to eq '#b0c' + end + end + + context 'when coverage is medium' do + before do + allow(badge).to receive(:status).and_return(75) + end + + it 'is orange-yellow' do + expect(template.value_color).to eq '#dfb317' + end + end + + context 'when coverage is low' do + before do + allow(badge).to receive(:status).and_return(50) + end + + it 'is red' do + expect(template.value_color).to eq '#e05d44' + end + end + + context 'when coverage is unknown' do + before do + allow(badge).to receive(:status).and_return(nil) + end + + it 'is grey' do + expect(template.value_color).to eq '#9f9f9f' + end + end + end + + describe '#width' do + context 'when coverage is known' do + it 'returns the key width plus value width' do + expect(template.width).to eq 94 + end + end + + context 'when coverage is unknown' do + before do + allow(badge).to receive(:status).and_return(nil) + end + + it 'returns key width plus wider value width' do + expect(template.width).to eq 120 + end + end + end +end From dbb9d6a726285bdf59cc789aac584e712ea1280c Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Thu, 11 Aug 2016 15:01:14 +0200 Subject: [PATCH 09/18] Extract base abstract template for badges --- lib/gitlab/badge/build/template.rb | 18 +--------- lib/gitlab/badge/coverage/template.rb | 19 +---------- lib/gitlab/badge/template.rb | 49 +++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 35 deletions(-) create mode 100644 lib/gitlab/badge/template.rb diff --git a/lib/gitlab/badge/build/template.rb b/lib/gitlab/badge/build/template.rb index f52589ff736..2b95ddfcb53 100644 --- a/lib/gitlab/badge/build/template.rb +++ b/lib/gitlab/badge/build/template.rb @@ -6,7 +6,7 @@ module Gitlab # # Template object will be passed to badge.svg.erb template. # - class Template + class Template < Badge::Template STATUS_COLOR = { success: '#4c1', failed: '#e05d44', @@ -38,25 +38,9 @@ module Gitlab 54 end - def key_color - '#555' - end - def value_color STATUS_COLOR[@status.to_sym] || STATUS_COLOR[:unknown] end - - def key_text_anchor - key_width / 2 - end - - def value_text_anchor - key_width + (value_width / 2) - end - - def width - key_width + value_width - end end end end diff --git a/lib/gitlab/badge/coverage/template.rb b/lib/gitlab/badge/coverage/template.rb index 6f9a38b07dc..49a10d3e8e1 100644 --- a/lib/gitlab/badge/coverage/template.rb +++ b/lib/gitlab/badge/coverage/template.rb @@ -6,7 +6,7 @@ module Gitlab # # Template object will be passed to badge.svg.erb template. # - class Template + class Template < Badge::Template STATUS_COLOR = { good: '#4c1', acceptable: '#b0c', @@ -36,13 +36,8 @@ module Gitlab @status ? 32 : 58 end - def key_color - '#555' - end - def value_color case @status - when nil then STATUS_COLOR[:unknown] when 95..100 then STATUS_COLOR[:good] when 90..95 then STATUS_COLOR[:acceptable] when 75..90 then STATUS_COLOR[:medium] @@ -51,18 +46,6 @@ module Gitlab STATUS_COLOR[:unknown] end end - - def key_text_anchor - key_width / 2 - end - - def value_text_anchor - key_width + (value_width / 2) - end - - def width - key_width + value_width - end end end end diff --git a/lib/gitlab/badge/template.rb b/lib/gitlab/badge/template.rb new file mode 100644 index 00000000000..bfeb0052642 --- /dev/null +++ b/lib/gitlab/badge/template.rb @@ -0,0 +1,49 @@ +module Gitlab + module Badge + ## + # Abstract template class for badges + # + class Template + def initialize(badge) + @entity = badge.entity + @status = badge.status + end + + def key_text + raise NotImplementedError + end + + def value_text + raise NotImplementedError + end + + def key_width + raise NotImplementedError + end + + def value_width + raise NotImplementedError + end + + def value_color + raise NotImplementedError + end + + def key_color + '#555' + end + + def key_text_anchor + key_width / 2 + end + + def value_text_anchor + key_width + (value_width / 2) + end + + def width + key_width + value_width + end + end + end +end From 3e481f154f8e93a54cef8216c70ad5ab2d91f0f1 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Thu, 11 Aug 2016 15:04:37 +0200 Subject: [PATCH 10/18] Add metadata and template methods for coverage badge --- lib/gitlab/badge/coverage/report.rb | 8 ++++++++ spec/lib/gitlab/badge/coverage/report_spec.rb | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/gitlab/badge/coverage/report.rb b/lib/gitlab/badge/coverage/report.rb index f06142003e3..3d56ea3e47a 100644 --- a/lib/gitlab/badge/coverage/report.rb +++ b/lib/gitlab/badge/coverage/report.rb @@ -29,6 +29,14 @@ module Gitlab @coverage.to_i end + def metadata + @metadata ||= Coverage::Metadata.new(self) + end + + def template + @template ||= Coverage::Template.new(self) + end + private def raw_coverage diff --git a/spec/lib/gitlab/badge/coverage/report_spec.rb b/spec/lib/gitlab/badge/coverage/report_spec.rb index 46b14873ee9..1ff49602486 100644 --- a/spec/lib/gitlab/badge/coverage/report_spec.rb +++ b/spec/lib/gitlab/badge/coverage/report_spec.rb @@ -14,6 +14,18 @@ describe Gitlab::Badge::Coverage::Report do end end + describe '#metadata' do + it 'returns correct metadata' do + expect(badge.metadata.image_url).to include 'coverage.svg' + end + end + + describe '#template' do + it 'returns correct template' do + expect(badge.template.key_text).to eq 'coverage' + end + end + shared_examples 'unknown coverage report' do context 'particular job specified' do let(:job_name) { '' } From b6ca47f6d4ac80150759deeecf4d0e8dedcc9b88 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Thu, 11 Aug 2016 15:17:13 +0200 Subject: [PATCH 11/18] Add method for coverage badge in badges controller --- app/controllers/projects/badges_controller.rb | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb index e026ceaf757..6c25cd83a24 100644 --- a/app/controllers/projects/badges_controller.rb +++ b/app/controllers/projects/badges_controller.rb @@ -4,11 +4,24 @@ class Projects::BadgesController < Projects::ApplicationController before_action :no_cache_headers, except: [:index] def build - badge = Gitlab::Badge::Build::Status.new(project, params[:ref]) + build_status = Gitlab::Badge::Build::Status + .new(project, params[:ref]) + render_badge build_status + end + + def coverage + coverage_report = Gitlab::Badge::Coverage::Report + .new(project, params[:ref], params[:job]) + + render_badge coverage_report + end + + private + + def render_badge(badge) respond_to do |format| format.html { render_404 } - format.svg do render 'badge', locals: { badge: badge.template } end From b646adef131eb41521ca0a56884d5b3862c4f5ef Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Fri, 12 Aug 2016 14:30:17 +0200 Subject: [PATCH 12/18] Expose coverage report badge in pipeline settings --- .../projects/pipelines_settings_controller.rb | 8 ++- .../pipelines_settings/show.html.haml | 52 ++++++++++--------- spec/features/projects/badges/list_spec.rb | 44 +++++++++++----- 3 files changed, 66 insertions(+), 38 deletions(-) diff --git a/app/controllers/projects/pipelines_settings_controller.rb b/app/controllers/projects/pipelines_settings_controller.rb index fe7cb748f43..9136633b87a 100644 --- a/app/controllers/projects/pipelines_settings_controller.rb +++ b/app/controllers/projects/pipelines_settings_controller.rb @@ -3,7 +3,13 @@ class Projects::PipelinesSettingsController < Projects::ApplicationController def show @ref = params[:ref] || @project.default_branch || 'master' - @build_badge = Gitlab::Badge::Build::Status.new(@project, @ref).metadata + + @badges = [Gitlab::Badge::Build::Status, + Gitlab::Badge::Coverage::Report] + + @badges.map! do |badge| + badge.new(@project, @ref).metadata + end end def update diff --git a/app/views/projects/pipelines_settings/show.html.haml b/app/views/projects/pipelines_settings/show.html.haml index 228bad36ebd..5570dc0481b 100644 --- a/app/views/projects/pipelines_settings/show.html.haml +++ b/app/views/projects/pipelines_settings/show.html.haml @@ -77,27 +77,31 @@ %hr .row.prepend-top-default - .col-lg-3.profile-settings-sidebar - %h4.prepend-top-0 - Builds Badge - .col-lg-9 - .prepend-top-10 - .panel.panel-default - .panel-heading - %b Builds badge · - = @build_badge.to_html - .pull-right - = render 'shared/ref_switcher', destination: 'badges', align_right: true - .panel-body - .row - .col-md-2.text-center - Markdown - .col-md-10.code.js-syntax-highlight - = highlight('.md', @build_badge.to_markdown) - .row - %hr - .row - .col-md-2.text-center - HTML - .col-md-10.code.js-syntax-highlight - = highlight('.html', @build_badge.to_html) + - @badges.each do |badge| + .row{ class: badge.title.gsub(' ', '-') } + .col-lg-3.profile-settings-sidebar + %h4.prepend-top-0 + = badge.title.capitalize + .col-lg-9 + .prepend-top-10 + .panel.panel-default + .panel-heading + %b + = badge.title.capitalize + · + = badge.to_html + .pull-right + = render 'shared/ref_switcher', destination: 'badges', align_right: true + .panel-body + .row + .col-md-2.text-center + Markdown + .col-md-10.code.js-syntax-highlight + = highlight('.md', badge.to_markdown) + .row + %hr + .row + .col-md-2.text-center + HTML + .col-md-10.code.js-syntax-highlight + = highlight('.html', badge.to_html) diff --git a/spec/features/projects/badges/list_spec.rb b/spec/features/projects/badges/list_spec.rb index 75166bca119..67a4a5d1ab1 100644 --- a/spec/features/projects/badges/list_spec.rb +++ b/spec/features/projects/badges/list_spec.rb @@ -9,25 +9,43 @@ feature 'list of badges' do visit namespace_project_pipelines_settings_path(project.namespace, project) end - scenario 'user displays list of badges' do - expect(page).to have_content 'build status' - expect(page).to have_content 'Markdown' - expect(page).to have_content 'HTML' - expect(page).to have_css('.highlight', count: 2) - expect(page).to have_xpath("//img[@alt='build status']") + scenario 'user wants to see build status badge' do + page.within('.build-status') do + expect(page).to have_content 'build status' + expect(page).to have_content 'Markdown' + expect(page).to have_content 'HTML' + expect(page).to have_css('.highlight', count: 2) + expect(page).to have_xpath("//img[@alt='build status']") - page.within('.highlight', match: :first) do - expect(page).to have_content 'badges/master/build.svg' + page.within('.highlight', match: :first) do + expect(page).to have_content 'badges/master/build.svg' + end end end - scenario 'user changes current ref on badges list page', js: true do - first('.js-project-refs-dropdown').click + scenario 'user wants to see coverage report badge' do + page.within('.coverage-report') do + expect(page).to have_content 'coverage report' + expect(page).to have_content 'Markdown' + expect(page).to have_content 'HTML' + expect(page).to have_css('.highlight', count: 2) + expect(page).to have_xpath("//img[@alt='coverage report']") - page.within '.project-refs-form' do - click_link 'improve/awesome' + page.within('.highlight', match: :first) do + expect(page).to have_content 'badges/master/coverage.svg' + end end + end - expect(page).to have_content 'badges/improve/awesome/build.svg' + scenario 'user changes current ref of build status badge', js: true do + page.within('.build-status') do + first('.js-project-refs-dropdown').click + + page.within '.project-refs-form' do + click_link 'improve/awesome' + end + + expect(page).to have_content 'badges/improve/awesome/build.svg' + end end end From eec0f5da873a5730e71560330277bf83958a6146 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Fri, 12 Aug 2016 14:32:46 +0200 Subject: [PATCH 13/18] Extract pipeline badges to the separate view partial --- .../pipelines_settings/_badges.html.haml | 28 ++++++++++++++++++ .../pipelines_settings/show.html.haml | 29 +------------------ 2 files changed, 29 insertions(+), 28 deletions(-) create mode 100644 app/views/projects/pipelines_settings/_badges.html.haml diff --git a/app/views/projects/pipelines_settings/_badges.html.haml b/app/views/projects/pipelines_settings/_badges.html.haml new file mode 100644 index 00000000000..436ae4c237a --- /dev/null +++ b/app/views/projects/pipelines_settings/_badges.html.haml @@ -0,0 +1,28 @@ +- badges.each do |badge| + .row{ class: badge.title.gsub(' ', '-') } + .col-lg-3.profile-settings-sidebar + %h4.prepend-top-0 + = badge.title.capitalize + .col-lg-9 + .prepend-top-10 + .panel.panel-default + .panel-heading + %b + = badge.title.capitalize + · + = badge.to_html + .pull-right + = render 'shared/ref_switcher', destination: 'badges', align_right: true + .panel-body + .row + .col-md-2.text-center + Markdown + .col-md-10.code.js-syntax-highlight + = highlight('.md', badge.to_markdown) + .row + %hr + .row + .col-md-2.text-center + HTML + .col-md-10.code.js-syntax-highlight + = highlight('.html', badge.to_html) diff --git a/app/views/projects/pipelines_settings/show.html.haml b/app/views/projects/pipelines_settings/show.html.haml index 5570dc0481b..3213fe07ef5 100644 --- a/app/views/projects/pipelines_settings/show.html.haml +++ b/app/views/projects/pipelines_settings/show.html.haml @@ -77,31 +77,4 @@ %hr .row.prepend-top-default - - @badges.each do |badge| - .row{ class: badge.title.gsub(' ', '-') } - .col-lg-3.profile-settings-sidebar - %h4.prepend-top-0 - = badge.title.capitalize - .col-lg-9 - .prepend-top-10 - .panel.panel-default - .panel-heading - %b - = badge.title.capitalize - · - = badge.to_html - .pull-right - = render 'shared/ref_switcher', destination: 'badges', align_right: true - .panel-body - .row - .col-md-2.text-center - Markdown - .col-md-10.code.js-syntax-highlight - = highlight('.md', badge.to_markdown) - .row - %hr - .row - .col-md-2.text-center - HTML - .col-md-10.code.js-syntax-highlight - = highlight('.html', badge.to_html) + = render partial: 'badges', object: @badges From 0c81279ea2da8751c58d211d9eb857d227f4318d Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Fri, 12 Aug 2016 15:10:02 +0200 Subject: [PATCH 14/18] Render collection of badges instead of using iterator --- .../pipelines_settings/_badge.html.haml | 27 ++++++++++++++++++ .../pipelines_settings/_badges.html.haml | 28 ------------------- .../pipelines_settings/show.html.haml | 2 +- 3 files changed, 28 insertions(+), 29 deletions(-) create mode 100644 app/views/projects/pipelines_settings/_badge.html.haml delete mode 100644 app/views/projects/pipelines_settings/_badges.html.haml diff --git a/app/views/projects/pipelines_settings/_badge.html.haml b/app/views/projects/pipelines_settings/_badge.html.haml new file mode 100644 index 00000000000..7b7fa56d993 --- /dev/null +++ b/app/views/projects/pipelines_settings/_badge.html.haml @@ -0,0 +1,27 @@ +.row{ class: badge.title.gsub(' ', '-') } + .col-lg-3.profile-settings-sidebar + %h4.prepend-top-0 + = badge.title.capitalize + .col-lg-9 + .prepend-top-10 + .panel.panel-default + .panel-heading + %b + = badge.title.capitalize + · + = badge.to_html + .pull-right + = render 'shared/ref_switcher', destination: 'badges', align_right: true + .panel-body + .row + .col-md-2.text-center + Markdown + .col-md-10.code.js-syntax-highlight + = highlight('.md', badge.to_markdown) + .row + %hr + .row + .col-md-2.text-center + HTML + .col-md-10.code.js-syntax-highlight + = highlight('.html', badge.to_html) diff --git a/app/views/projects/pipelines_settings/_badges.html.haml b/app/views/projects/pipelines_settings/_badges.html.haml deleted file mode 100644 index 436ae4c237a..00000000000 --- a/app/views/projects/pipelines_settings/_badges.html.haml +++ /dev/null @@ -1,28 +0,0 @@ -- badges.each do |badge| - .row{ class: badge.title.gsub(' ', '-') } - .col-lg-3.profile-settings-sidebar - %h4.prepend-top-0 - = badge.title.capitalize - .col-lg-9 - .prepend-top-10 - .panel.panel-default - .panel-heading - %b - = badge.title.capitalize - · - = badge.to_html - .pull-right - = render 'shared/ref_switcher', destination: 'badges', align_right: true - .panel-body - .row - .col-md-2.text-center - Markdown - .col-md-10.code.js-syntax-highlight - = highlight('.md', badge.to_markdown) - .row - %hr - .row - .col-md-2.text-center - HTML - .col-md-10.code.js-syntax-highlight - = highlight('.html', badge.to_html) diff --git a/app/views/projects/pipelines_settings/show.html.haml b/app/views/projects/pipelines_settings/show.html.haml index 3213fe07ef5..8c7222bfe3d 100644 --- a/app/views/projects/pipelines_settings/show.html.haml +++ b/app/views/projects/pipelines_settings/show.html.haml @@ -77,4 +77,4 @@ %hr .row.prepend-top-default - = render partial: 'badges', object: @badges + = render partial: 'badge', collection: @badges From b13e1d795a06499d0264b1103108057a7862826f Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Fri, 12 Aug 2016 15:26:55 +0200 Subject: [PATCH 15/18] Add small corrections to test coverage report badge --- lib/gitlab/badge/coverage/template.rb | 4 ++-- spec/lib/gitlab/badge/coverage/template_spec.rb | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/gitlab/badge/coverage/template.rb b/lib/gitlab/badge/coverage/template.rb index 49a10d3e8e1..06e0d084e9f 100644 --- a/lib/gitlab/badge/coverage/template.rb +++ b/lib/gitlab/badge/coverage/template.rb @@ -9,7 +9,7 @@ module Gitlab class Template < Badge::Template STATUS_COLOR = { good: '#4c1', - acceptable: '#b0c', + acceptable: '#a3c51c', medium: '#dfb317', low: '#e05d44', unknown: '#9f9f9f' @@ -33,7 +33,7 @@ module Gitlab end def value_width - @status ? 32 : 58 + @status ? 36 : 58 end def value_color diff --git a/spec/lib/gitlab/badge/coverage/template_spec.rb b/spec/lib/gitlab/badge/coverage/template_spec.rb index a45de1dc677..383bae6e087 100644 --- a/spec/lib/gitlab/badge/coverage/template_spec.rb +++ b/spec/lib/gitlab/badge/coverage/template_spec.rb @@ -37,7 +37,7 @@ describe Gitlab::Badge::Coverage::Template do describe '#value_width' do context 'when coverage is known' do it 'is narrower when coverage is known' do - expect(template.value_width).to eq 32 + expect(template.value_width).to eq 36 end end @@ -75,7 +75,7 @@ describe Gitlab::Badge::Coverage::Template do end it 'is green-orange' do - expect(template.value_color).to eq '#b0c' + expect(template.value_color).to eq '#a3c51c' end end @@ -113,7 +113,7 @@ describe Gitlab::Badge::Coverage::Template do describe '#width' do context 'when coverage is known' do it 'returns the key width plus value width' do - expect(template.width).to eq 94 + expect(template.width).to eq 98 end end From dfd913892993338cfcf50d3340a1582b18ae8cac Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Mon, 15 Aug 2016 11:41:01 +0200 Subject: [PATCH 16/18] Add feature specs for test coverage badge --- .../features/projects/badges/coverage_spec.rb | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 spec/features/projects/badges/coverage_spec.rb diff --git a/spec/features/projects/badges/coverage_spec.rb b/spec/features/projects/badges/coverage_spec.rb new file mode 100644 index 00000000000..af86d3c338a --- /dev/null +++ b/spec/features/projects/badges/coverage_spec.rb @@ -0,0 +1,73 @@ +require 'spec_helper' + +feature 'test coverage badge' do + given!(:user) { create(:user) } + given!(:project) { create(:project, :private) } + + given!(:pipeline) do + create(:ci_pipeline, project: project, + ref: 'master', + sha: project.commit.id) + end + + context 'when user has access to view badge' do + background do + project.team << [user, :developer] + login_as(user) + end + + scenario 'user requests coverage badge image for pipeline' do + create_job(coverage: 100, name: 'test:1') + create_job(coverage: 90, name: 'test:2') + + show_test_coverage_badge + + expect_coverage_badge('95%') + end + + scenario 'user requests coverage badge for specific job' do + create_job(coverage: 50, name: 'test:1') + create_job(coverage: 50, name: 'test:2') + create_job(coverage: 85, name: 'coverage') + + show_test_coverage_badge(job: 'coverage') + + expect_coverage_badge('85%') + end + + scenario 'user requests coverage badge for pipeline without coverage' do + create_job(coverage: nil, name: 'test') + + show_test_coverage_badge + + expect_coverage_badge('unknown') + end + end + + context 'when user does not have access to view badge' do + background { login_as(user) } + + scenario 'user requests test coverage badge image' do + show_test_coverage_badge + + expect(page).to have_http_status(404) + end + end + + def create_job(coverage:, name:) + create(:ci_build, name: name, + coverage: coverage, + pipeline: pipeline) + end + + def show_test_coverage_badge(job: nil) + visit coverage_namespace_project_badges_path( + project.namespace, project, ref: :master, job: job, format: :svg) + end + + def expect_coverage_badge(coverage) + svg = Nokogiri::XML.parse(page.body) + expect(page.response_headers['Content-Type']).to include('image/svg+xml') + expect(svg.at(%Q{text:contains("#{coverage}")})).to be_truthy + end +end From a0ed41a52f189dd8ed98262f7e67aa23daf9f9e1 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Mon, 15 Aug 2016 15:13:56 +0200 Subject: [PATCH 17/18] Add documentation for test coverage report badge --- doc/ci/pipelines.md | 35 +++++++++++++++++++++++++++++++++++ doc/ci/quick_start/README.md | 12 ++---------- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/doc/ci/pipelines.md b/doc/ci/pipelines.md index 48a9f994759..d90d7aca4fd 100644 --- a/doc/ci/pipelines.md +++ b/doc/ci/pipelines.md @@ -32,6 +32,41 @@ project. Clicking on a pipeline will show the builds that were run for that pipeline. +## Badges + +There are build status and test coverage report badges available. + +Go to pipeline settings to see available badges and code you can use to embed +badges in the `README.md` or your website. + +### Build status badge + +You can access a build status badge image using following link: + +``` +http://example.gitlab.com/namespace/project/badges/branch/build.svg +``` + +### Test coverage report badge + +GitLab makes it possible to define the regular expression for coverage report, +that each build log will be matched against. This means that each build in the +pipeline can have the test coverage percentage value defined. + +You can access test coverage badge using following link: + +``` +http://example.gitlab.com/namespace/project/badges/branch/coverage.svg +``` + +If you would like to get the coverage report from the specific job, you can add +a `job=coverage_job_name` parameter to the URL. For example, it is possible to +use following Markdown code to embed the est coverage report into `README.md`: + +```markdown +![coverage](http://gitlab.com/gitlab-org/gitlab-ce/badges/master/coverage.svg?job=coverage) +``` + [builds]: #builds [jobs]: yaml/README.md#jobs [stages]: yaml/README.md#stages diff --git a/doc/ci/quick_start/README.md b/doc/ci/quick_start/README.md index 6a3c416d995..c835ebc2d44 100644 --- a/doc/ci/quick_start/README.md +++ b/doc/ci/quick_start/README.md @@ -218,21 +218,13 @@ project's settings. For more information read the [Builds emails service documentation](../../project_services/builds_emails.md). -## Builds badge - -You can access a builds badge image using following link: - -``` -http://example.gitlab.com/namespace/project/badges/branch/build.svg -``` - -Awesome! You started using CI in GitLab! - ## Examples Visit the [examples README][examples] to see a list of examples using GitLab CI with various languages. +Awesome! You started using CI in GitLab! + [runner-install]: https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/tree/master#install-gitlab-runner [blog-ci]: https://about.gitlab.com/2015/05/06/why-were-replacing-gitlab-ci-jobs-with-gitlab-ci-dot-yml/ [examples]: ../examples/README.md From 48c4c8f06c9b82c7f54a663e27514da5e9a9e2f8 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Mon, 15 Aug 2016 15:16:46 +0200 Subject: [PATCH 18/18] Add Changelog entry for test coverage report badge --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 008c5c64284..f58029f1da4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 8.11.0 (unreleased) + - Add test coverage report badge. !5708 - Remove the http_parser.rb dependency by removing the tinder gem. !5758 (tbalthazar) - Ability to specify branches for Pivotal Tracker integration (Egor Lynko) - Fix don't pass a local variable called `i` to a partial. !20510 (herminiotorres)