From 94469be1ca2286866ff83df458ec35e357f0aff7 Mon Sep 17 00:00:00 2001 From: Benjamin Fleischer Date: Thu, 27 Aug 2015 01:13:36 -0500 Subject: [PATCH] Add test coverage; account for no artifacts on CI Drop coverage a bit for JRuby and Rubinius because they don't generate the same Coverage as CRuby --- .simplecov | 95 +++++++++++++++++++++++++++++++++++++++ Gemfile | 3 ++ Rakefile | 5 +++ test/support/simplecov.rb | 6 +++ test/test_helper.rb | 11 +++++ 5 files changed, 120 insertions(+) create mode 100644 .simplecov create mode 100644 test/support/simplecov.rb diff --git a/.simplecov b/.simplecov new file mode 100644 index 00000000..204011f8 --- /dev/null +++ b/.simplecov @@ -0,0 +1,95 @@ +# 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 + +## DEFINE VARIABLES +@minimum_coverage = ENV.fetch('COVERAGE_MINIMUM') { + case (defined?(RUBY_ENGINE) && RUBY_ENGINE) || "ruby" + when 'jruby', 'rbx' + 96.0 + else + 98.3 + end +}.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 = STDOUT +# rubocop:enable Style/DoubleNegation + +## CONFIGURE SIMPLECOV +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 (before activating SimpleCov) +require 'coverage' +Coverage.start + +## ADD SOME CUSTOM REPORTING AT EXIT +SimpleCov.at_exit do + header = "#{'*' * 20} SimpleCov Results #{'*' * 20}" + @output.puts + @output.puts header + @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 + @output.puts + @output.puts '*' * header.size +end + +## CAPTURE CONFIG IN CLOSURE 'AppCoverage.start' +## to defer running until test/test_helper.rb is loaded. +# 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 diff --git a/Gemfile b/Gemfile index a9846cb0..c7531840 100644 --- a/Gemfile +++ b/Gemfile @@ -29,6 +29,9 @@ group :test do gem 'activerecord' gem 'sqlite3', platform: :ruby gem 'activerecord-jdbcsqlite3-adapter', platform: :jruby + +group :test, :development do + gem 'simplecov', '~> 0.10', require: false end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem diff --git a/Rakefile b/Rakefile index cc454b66..cefdc423 100644 --- a/Rakefile +++ b/Rakefile @@ -1,3 +1,8 @@ +begin + require 'simplecov' +rescue LoadError +end + require 'bundler/gem_tasks' begin diff --git a/test/support/simplecov.rb b/test/support/simplecov.rb new file mode 100644 index 00000000..2a249972 --- /dev/null +++ b/test/support/simplecov.rb @@ -0,0 +1,6 @@ +# https://github.com/colszowka/simplecov/pull/400 +# https://github.com/ruby/ruby/blob/trunk/lib/English.rb +unless defined?(English) + # The exception object passed to +raise+. + alias $ERROR_INFO $! # rubocop:disable Style/SpecialGlobalVars +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 980b04f8..08499b40 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,5 +1,16 @@ require 'bundler/setup' +begin + require 'simplecov' + # HACK: till https://github.com/colszowka/simplecov/pull/400 is merged and released. + # Otherwise you may get: + # simplecov-0.10.0/lib/simplecov/defaults.rb:50: warning: global variable `$ERROR_INFO' not initialized + require 'support/simplecov' + AppCoverage.start +rescue LoadError + STDERR.puts 'Running without SimpleCov' +end + require 'timecop' require 'rails' require 'action_controller'