Skip to content

Commit

Permalink
Add test coverage; account for no artifacts on CI
Browse files Browse the repository at this point in the history
  • Loading branch information
bf4 committed Aug 21, 2015
1 parent fc7b9c3 commit 9b4a65b
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 15 deletions.
77 changes: 77 additions & 0 deletions .simplecov
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# https://github.com/colszowka/simplecov#using-simplecov-for-centralized-config
# see https://github.com/colszowka/simplecov/blob/master/lib/simplecov/defaults.rb
# vim: set ft=ruby
@minimum_coverage = ENV.fetch('COVERAGE_MINIMUM') { 98.3 }.to_f.round(2)
# rubocop:disable Style/DoubleNegation
ENV['FULL_BUILD'] ||= ENV['CI']
@running_ci = !!(ENV['FULL_BUILD'] =~ /\Atrue\z/i)
@generate_report = @running_ci || !!(ENV['COVERAGE'] =~ /\Atrue\z/i)
@output = STDERR
# rubocop:enable Style/DoubleNegation

SimpleCov.pid = $$ # In case there's any forking

SimpleCov.profiles.define 'app' do
coverage_dir 'coverage'
load_profile 'test_frameworks'

add_group 'Libraries', 'lib'

add_group 'Long files' do |src_file|
src_file.lines.count > 100
end
class MaxLinesFilter < SimpleCov::Filter
def matches?(source_file)
source_file.lines.count < filter_argument
end
end
add_group 'Short files', MaxLinesFilter.new(5)

# Exclude these paths from analysis
add_filter '/config/'
add_filter '/db/'
add_filter 'tasks'
end

## START TRACKING COVERAGE
require 'coverage'
Coverage.start

# rubocop:disable Style/MultilineBlockChain
AppCoverage = Class.new do
def initialize(&block)
@block = block
end

def start
@block.call
end
end.new do
SimpleCov.start 'app'
if @generate_report
if @running_ci
@output.puts '[COVERAGE] Running with SimpleCov Simple Formatter'
formatters = [SimpleCov::Formatter::SimpleFormatter]
else
@output.puts '[COVERAGE] Running with SimpleCov HTML Formatter'
formatters = [SimpleCov::Formatter::HTMLFormatter]
end
else
formatters = []
end
SimpleCov.formatters = formatters
end
# rubocop:enable Style/MultilineBlockChain
SimpleCov.at_exit do
@output.puts "*" * 50
@output.puts SimpleCov.result.format!
percent = Float(SimpleCov.result.covered_percent)
if percent < @minimum_coverage
@output.puts "Spec coverage was not high enough: "\
"#{percent.round(2)} is < #{@minimum_coverage}%\n"
exit 1 if @generate_report
else
@output.puts "Nice job! Spec coverage (#{percent.round(2)}) "\
"is still at or above #{@minimum_coverage}%\n"
end
end
16 changes: 10 additions & 6 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@ source 'https://rubygems.org'
# Specify your gem's dependencies in active_model_serializers.gemspec
gemspec

gem "minitest"
gem 'minitest'

version = ENV["RAILS_VERSION"] || "4.2"
version = ENV['RAILS_VERSION'] || '4.2'

if version == "master"
gem "rails", github: "rails/rails"
if version == 'master'
gem 'rails', github: 'rails/rails'

# ugh https://github.com/rails/rails/issues/16063#issuecomment-48090125
gem "arel", github: "rails/arel"
gem 'arel', github: 'rails/arel'
else
gem "rails", "~> #{version}.0"
gem 'rails', "~> #{version}.0"
end

group :test, :development do
gem 'simplecov', '~> 0.10', require: false
end
7 changes: 6 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
require "bundler/gem_tasks"
begin
require 'simplecov'
rescue LoadError
end

require 'bundler/gem_tasks'

require 'rake/testtask'

Expand Down
41 changes: 34 additions & 7 deletions test/capture_warnings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,24 @@ def initialize(fail_on_warnings = true)
end

def before_tests
$stderr.reopen(stderr_file.path)
$VERBOSE = true
at_exit { $stderr.reopen(STDERR) }
@restore_output = capture_output(stderr_file)
end

def after_tests
stderr_file.rewind
lines = stderr_file.read.split("\n").uniq
stderr_file.close!

$stderr.reopen(STDERR)
# $stderr.reopen(STDERR)
@restore_output.call

app_warnings, other_warnings = lines.partition { |line|
line.include?(app_root) && !line.include?(bundle_dir)
}

if app_warnings.any?
puts <<-WARNINGS
STDERR.puts <<-WARNINGS
#{'-' * 30} app warnings: #{'-' * 30}
#{app_warnings.join("\n")}
Expand All @@ -41,9 +41,9 @@ def after_tests

if other_warnings.any?
File.write(File.join(output_dir, "warnings.txt"), other_warnings.join("\n") << "\n")
puts
puts "Non-app warnings written to tmp/warnings.txt"
puts
STDERR.puts
STDERR.puts "Non-app warnings written to tmp/warnings.txt"
STDERR.puts
end

# fail the build...
Expand All @@ -54,4 +54,31 @@ def after_tests

private
attr_reader :stderr_file, :app_root, :output_dir, :bundle_dir, :fail_on_warnings

# From episode 029 of Ruby Tapas by Avdi
# https://rubytapas.dpdcart.com/subscriber/post?id=88
def capture_output(output, stream = STDERR)
old_stdout = stream.clone
pipe_r, pipe_w = IO.pipe
pipe_r.sync = true
reader = Thread.new do
begin
loop do
output << pipe_r.readpartial(1024)
end
rescue EOFError
end
end
stream.reopen(pipe_w)
ensure
restore_output = proc do
stream.reopen(old_stdout)
pipe_w.close if pipe_w.respond_to?(:closed?) && !pipe_w.closed?
reader.join if reader.alive?
pipe_r.close if pipe_r.respond_to?(:closed?) && !pipe_r.closed?
end
at_exit(&restore_output)
return restore_output
end

end
9 changes: 8 additions & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
require 'bundler/setup'

begin
require 'simplecov'
AppCoverage.start
rescue LoadError
STDERR.puts 'Running without SimpleCov'
end

require 'timecop'
require 'rails'
require 'action_controller'
Expand All @@ -14,7 +21,7 @@
require "capture_warnings"
@capture_warnings = CaptureWarnings.new(fail_build = false)
@capture_warnings.before_tests
at_exit do
Minitest.after_run do
@capture_warnings.after_tests
end
require 'active_model_serializers'
Expand Down

0 comments on commit 9b4a65b

Please sign in to comment.