Commit 804fa437 authored by Douwe Maan's avatar Douwe Maan

Merge branch 'feature/test-coverage-badge' into 'master'

Add test coverage badge

## What does this MR do?

This MR adds a test coverage badge.

Test coverage badge will be a SVG image you can embed in README.md or on your website that will be created dynamically by GitLab, to show information about how much of the code is being covered by tests. In addition to coverage-regexp feature we currently have, this feature will make it possible to use the coverage data obtained from the build log. We will support both - pipeline coverage, or test coverage for particular job in the pipeline. 

![coverage_badges](/uploads/dfa307339eb58c8138e551b42c0d8756/coverage_badges.png)

![coverage_badge](/uploads/30406e4bdcf979b2900ffe8996728c97/coverage_badge.png)

## What are the relevant issue numbers?

Closes #3714

## Screenshots (if relevant)

## Does this MR meet the acceptance criteria?

- [x] [CHANGELOG](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CHANGELOG) entry added
- [x] [Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md)
- [ ] ~~API support added~~
- Tests
  - [x] Added for this feature/bug
  - [x] All builds are passing
- [x] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides)
- [x] Branch has no merge conflicts with `master` (if you do - rebase it please)
- [x] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)

See merge request !5708
parents 9618abcb 48c4c8f0
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)
......
......@@ -4,11 +4,24 @@ class Projects::BadgesController < Projects::ApplicationController
before_action :no_cache_headers, except: [:index]
def build
badge = Gitlab::Badge::Build.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
......
......@@ -3,7 +3,13 @@ class Projects::PipelinesSettingsController < Projects::ApplicationController
def show
@ref = params[:ref] || @project.default_branch || 'master'
@build_badge = Gitlab::Badge::Build.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
......
.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
&middot;
= 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)
......@@ -77,27 +77,4 @@
%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 &middot;
= @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)
= render partial: 'badge', collection: @badges
......@@ -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
......
......@@ -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
......
......@@ -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
......
module Gitlab
module Badge
class Base
def entity
raise NotImplementedError
end
def status
raise NotImplementedError
end
def metadata
raise NotImplementedError
end
def template
raise NotImplementedError
end
end
end
end
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
module Gitlab
module Badge
class Build
module Build
##
# Class that describes build badge metadata
#
class Metadata
include Gitlab::Application.routes.url_helpers
include ActionView::Helpers::AssetTagHelper
include ActionView::Helpers::UrlHelper
def initialize(project, ref)
@project = project
@ref = ref
end
def to_html
link_to(image_tag(image_url, alt: 'build status'), link_url)
class Metadata < Badge::Metadata
def initialize(badge)
@project = badge.project
@ref = badge.ref
end
def to_markdown
"[![build status](#{image_url})](#{link_url})"
def title
'build status'
end
def image_url
......
module Gitlab
module Badge
module Build
##
# Build status badge
#
class Status < Badge::Base
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)
.status || 'unknown'
end
def metadata
@metadata ||= Build::Metadata.new(self)
end
def template
@template ||= Build::Template.new(self)
end
end
end
end
end
module Gitlab
module Badge
class Build
module Build
##
# Class that represents a build badge template.
#
# Template object will be passed to badge.svg.erb template.
#
class Template
class Template < Badge::Template
STATUS_COLOR = {
success: '#4c1',
failed: '#e05d44',
......@@ -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
......@@ -37,25 +38,8 @@ 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
STATUS_COLOR[@status.to_sym] || STATUS_COLOR[:unknown]
end
end
end
......
module Gitlab
module Badge
module Coverage
##
# Class that describes coverage badge metadata
#
class Metadata < Badge::Metadata
def initialize(badge)
@project = badge.project
@ref = badge.ref
@job = badge.job
end
def title
'coverage report'
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
module Gitlab
module Badge
module Coverage
##
# 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 entity
'coverage'
end
def status
@coverage ||= raw_coverage
return unless @coverage
@coverage.to_i
end
def metadata
@metadata ||= Coverage::Metadata.new(self)
end
def template
@template ||= Coverage::Template.new(self)
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
end
end
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 < Badge::Template
STATUS_COLOR = {
good: '#4c1',
acceptable: '#a3c51c',
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 ? 36 : 58
end
def value_color
case @status
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
end
end
end
end
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
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
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
......@@ -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']")
page.within('.highlight', match: :first) do
expect(page).to have_content 'badges/master/build.svg'
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'
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
scenario 'user changes current ref of build status badge', js: true do
page.within('.build-status') do
first('.js-project-refs-dropdown').click
expect(page).to have_content 'badges/improve/awesome/build.svg'
page.within '.project-refs-form' do
click_link 'improve/awesome'
end
expect(page).to have_content 'badges/improve/awesome/build.svg'
end
end
end
require 'spec_helper'
require 'lib/gitlab/badge/shared/metadata'
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(:a_href) { html.at('a') }
it_behaves_like 'badge metadata'
it 'points to link' do
expect(a_href[:href]).to eq badge.link_url
end
it 'contains clickable image' do
expect(a_href.children.first.name).to eq 'img'
describe '#title' do
it 'returns build status title' do
expect(metadata.title).to eq 'build status'
end
end
describe '#to_markdown' do
subject { badge.to_markdown }
it { is_expected.to include badge.image_url }
it { is_expected.to include badge.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
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' }
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 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 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 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 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)
......
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'
......
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 '#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'
end
end
describe '#link_url' do
it 'returns valid link' do
expect(metadata.link_url).to include 'commits/feature'
end
end
end
require 'spec_helper'
describe Gitlab::Badge::Coverage::Report do
let(:project) { create(:project) }
let(:job_name) { nil }
let(:badge) do
described_class.new(project, 'master', job_name)
end
describe '#entity' do
it 'describes a coverage' do
expect(badge.entity).to eq 'coverage'
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) { '' }
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
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 36
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 '#a3c51c'
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 98
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
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
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