Skip to content

Commit

Permalink
Integrate SimpleCov::RSpec into the project
Browse files Browse the repository at this point in the history
  • Loading branch information
jcouball committed Sep 15, 2024
1 parent 4fe44a8 commit 3869e9c
Show file tree
Hide file tree
Showing 13 changed files with 60 additions and 122 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ jobs:
- ruby: "jruby-9.4"
operating-system: windows-latest

env:
JRUBY_OPTS: --debug

steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
11 changes: 3 additions & 8 deletions lib/version_boss/gem/incrementable_version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,7 @@ class IncrementableVersion < Version
# @return [Boolean] true if the version string is a valid semver and meets the conditions above
#
def valid?
super && (
pre_release.empty? ||
(
pre_release_identifiers.size == 2 &&
pre_type.is_a?(String) &&
pre_number.is_a?(Integer)
)
)
super && (pre_release.empty? || (pre_release_identifiers.size == 2 && pre_number.is_a?(Integer)))
end

# The default pre-release identifier
Expand Down Expand Up @@ -194,9 +187,11 @@ def assert_is_a_pre_release_version
def assert_pre_type_is_valid(pre_type)
return if self.pre_type <= pre_type

# :nocov: JRuby coverage does not report this line correctly
message = 'Cannot increment the pre-release identifier ' \
"from '#{self.pre_type}' to '#{pre_type}' " \
"because '#{self.pre_type}' is lexically less than '#{pre_type}'"
# :nocov:

raise VersionBoss::Error, message
end
Expand Down
10 changes: 6 additions & 4 deletions lib/version_boss/gem/version_file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ class VersionFile
# @api private
#
def initialize(path, content_before, version, content_after)
raise VersionBoss::Error, 'version must be an IncrementableVersion' unless
version.is_a?(VersionBoss::Gem::IncrementableVersion)
unless version.is_a?(VersionBoss::Gem::IncrementableVersion)
raise VersionBoss::Error, 'version must be an IncrementableVersion'
end

@path = path
@content_before = content_before
Expand Down Expand Up @@ -92,8 +93,9 @@ def initialize(path, content_before, version, content_after)
# @api public
#
def version=(new_version)
raise VersionBoss::Error, 'new_version must be an IncrementableVersion' unless
new_version.is_a?(VersionBoss::Gem::IncrementableVersion)
unless new_version.is_a?(VersionBoss::Gem::IncrementableVersion)
raise VersionBoss::Error, 'new_version must be an IncrementableVersion'
end

@version = version
File.write(path, content_before + new_version.to_s + content_after)
Expand Down
2 changes: 2 additions & 0 deletions lib/version_boss/gem/version_file_sources/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ class Base
# @return [VersionBoss::Gem::VersionFile, nil] the version file or nil if no version file was found
#
def self.find
# :nocov: JRuby does not mark the following line as covered
Dir[glob].filter_map do |path|
# :nocov:
if (match = File.read(path).match(content_regexp))
version = VersionBoss::Gem::IncrementableVersion.new(match[:version])
VersionBoss::Gem::VersionFile.new(path, match[:content_before], version, match[:content_after])
Expand Down
6 changes: 5 additions & 1 deletion lib/version_boss/gem/version_file_sources/gemspec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,22 @@ module VersionFileSources
# @api public
#
class Gemspec < Base
# :nocov: JRuby does not mark the line with VersionBoss::Gem::REGEXP.source as covered

# The regexp to find the version and surrounding content within the gemspec
VERSION_REGEXP = /
\A
(?<content_before>
.*
\.version\s*=\s*(?<quote>['"])
)
(?<version>#{REGEXP.source})
(?<version>#{VersionBoss::Gem::REGEXP.source})
(?<content_after>\k<quote>.*)
\z
/xm

# :nocov:

private

# The version file regexp
Expand Down
4 changes: 4 additions & 0 deletions lib/version_boss/gem/version_file_sources/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ module VersionFileSources
# @api public
#
class Version < Base
# :nocov: JRuby does not mark the line with VersionBoss::Gem::REGEXP.source as covered

# The regexp to find the version and surrounding content within the version file
VERSION_REGEXP = /
\A
Expand All @@ -19,6 +21,8 @@ class Version < Base
\z
/x

# :nocov:

private

# The version file regexp
Expand Down
4 changes: 4 additions & 0 deletions lib/version_boss/gem/version_file_sources/version_rb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ module VersionFileSources
# @api public
#
class VersionRb < Base
# :nocov: JRuby does not mark the line with VersionBoss::Gem::REGEXP.source as covered

# The regexp to find the version and surrounding content within the version.rb file
VERSION_REGEXP = /
\A
Expand All @@ -22,6 +24,8 @@ class VersionRb < Base
\z
/xm

# :nocov:

private

# The version file regexp
Expand Down
12 changes: 4 additions & 8 deletions lib/version_boss/semver/incrementable_version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,12 @@ class IncrementableVersion < Version
# IncrementableVersion.new('1.2.3-alpha').valid? # => raise VersionBoss::Error
# IncrementableVersion.new('1.2.3-alpha.1.2').valid? # => raise VersionBoss::Error
# IncrementableVersion.new('1.2.3-alpha.one').valid? # => raise VersionBoss::Error
# IncrementableVersion.new('').valid? # => raise VersionBoss::Error
#
# @return [Boolean] true if the version string is a valid semver and meets the conditions above
#
def valid?
super && (
pre_release.empty? ||
(
pre_release_identifiers.size == 2 &&
pre_type.is_a?(String) &&
pre_number.is_a?(Integer)
)
)
super && (pre_release.empty? || (pre_release_identifiers.size == 2 && pre_number.is_a?(Integer)))
end

# The default pre-release identifier
Expand Down Expand Up @@ -170,9 +164,11 @@ def assert_is_a_pre_release_version
def assert_pre_type_is_valid(pre_type)
return if self.pre_type <= pre_type

# :nocov: JRuby coverage does not report this line correctly
message = 'Cannot increment the pre-release identifier ' \
"from '#{self.pre_type}' to '#{pre_type}' " \
"because '#{self.pre_type}' is lexically less than '#{pre_type}'"
# :nocov:

raise VersionBoss::Error, message
end
Expand Down
111 changes: 10 additions & 101 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -344,113 +344,22 @@
end
end

# Setup simplecov

# SimpleCov configuration
#
require 'simplecov'
require 'simplecov-lcov'
require 'json'

SimpleCov.formatters = [SimpleCov::Formatter::HTMLFormatter, SimpleCov::Formatter::LcovFormatter]

# Return `true` if the environment variable is set to a truthy value
#
# @example
# env_true?('COV_SHOW_UNCOVERED')
#
# @param name [String] the name of the environment variable
# @return [Boolean]
#
def env_true?(name)
value = ENV.fetch(name, '').downcase
%w[yes on true 1].include?(value)
end

# Return `true` if the environment variable is NOT set to a truthy value
#
# @example
# env_false?('COV_NO_FAIL')
#
# @param name [String] the name of the environment variable
# @return [Boolean]
#
def env_false?(name)
!env_true?(name)
end

# Return `true` if the the test run should fail if the coverage is below the threshold
#
# @return [Boolean]
#
def fail_on_low_coverage?
!(RSpec.configuration.dry_run? || env_true?('COV_NO_FAIL'))
end

# Return `true` if the the test run should show the lines not covered by tests
#
# @return [Boolean]
#
def show_lines_not_covered?
env_true?('COV_SHOW_UNCOVERED')
end

# Report if the test coverage was below the configured threshold
#
# The threshold is configured by setting the `test_coverage_threshold` variable
# in this file.
#
# Example:
#
# ```Ruby
# test_coverage_threshold = 100
# ```
#
# Coverage below the threshold will cause the rspec run to fail unless the
# `COV_NO_FAIL` environment variable is set to TRUE.
#
# ```Shell
# COV_NO_FAIL=TRUE rspec
# ```
#
# Example of running the tests in an infinite loop writing failures to `fail.txt`:
#
# ```Shell
# while true; do COV_NO_FAIL=TRUE rspec >> fail.txt; done
# ````
#
# The lines missing coverage will be displayed if the `COV_SHOW_UNCOVERED`
# environment variable is set to TRUE.
#
# ```Shell
# COV_SHOW_UNCOVERED=TRUE rspec
# ```
#
test_coverage_threshold = 100

SimpleCov.at_exit do
SimpleCov.result.format!
# rubocop:disable Style/StderrPuts
if SimpleCov.result.covered_percent < test_coverage_threshold
$stderr.puts
$stderr.print 'FAIL: ' if fail_on_low_coverage?
$stderr.puts "RSpec Test coverage fell below #{test_coverage_threshold}%"

if show_lines_not_covered?
$stderr.puts "\nThe following lines were not covered by tests:\n"
SimpleCov.result.files.each do |source_file| # SimpleCov::SourceFile
source_file.missed_lines.each do |line| # SimpleCov::SourceFile::Line
$stderr.puts " .#{source_file.project_filename}:#{line.number}"
end
end
end
require 'simplecov-rspec'

$stderr.puts
def ci_build? = ENV.fetch('GITHUB_ACTIONS', 'false') == 'true'

exit 1 if fail_on_low_coverage?
end
# rubocop:enable Style/StderrPuts
if ci_build?
SimpleCov.formatters = [
SimpleCov::Formatter::HTMLFormatter,
SimpleCov::Formatter::LcovFormatter
]
end

SimpleCov.start
SimpleCov::RSpec.start(list_uncovered_lines: ci_build?)

# Make sure to require your project AFTER SimpleCov.start
#
Expand Down
7 changes: 7 additions & 0 deletions spec/version_boss/gem/incrementable_version_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@
expect { subject }.to raise_error(VersionBoss::Error)
end
end

context 'when the version is an empty string' do
let(:version) { '' }
it 'is expected to raise an VersionBoss::Error' do
expect { subject }.to raise_error(VersionBoss::Error)
end
end
end

describe '#next_major' do
Expand Down
4 changes: 4 additions & 0 deletions spec/version_boss/gem/version_file_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ module VersionBoss
end
ORIGINAL_CONTENT

# :nocov: JRuby does not mark the #{new_version} as covered

let(:expected_content) { <<~UPDATED_CONTENT }
# frozen_string_literal: true
Expand All @@ -63,6 +65,8 @@ module VersionBoss
end
UPDATED_CONTENT

# :nocov:

around do |example|
Dir.mktmpdir do |dir|
Dir.chdir(dir) do
Expand Down
7 changes: 7 additions & 0 deletions spec/version_boss/semver/incrementable_version_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@
expect { subject }.to raise_error(VersionBoss::Error)
end
end

context 'when the version is an empty string' do
let(:version) { '' }
it 'is expected to raise an VersionBoss::Error' do
expect { subject }.to raise_error(VersionBoss::Error)
end
end
end

describe '#next_major' do
Expand Down
1 change: 1 addition & 0 deletions version_boss.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'rubocop', '~> 1.59'
spec.add_development_dependency 'simplecov', '~> 0.22'
spec.add_development_dependency 'simplecov-lcov', '~> 0.8'
spec.add_development_dependency 'simplecov-rspec', '~> 0.2'

unless RUBY_PLATFORM == 'java'
spec.add_development_dependency 'redcarpet', '~> 3.6'
Expand Down

0 comments on commit 3869e9c

Please sign in to comment.