simplecov 0.7.1 → 0.8.0.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. data/.travis.yml +9 -2
  2. data/CHANGELOG.md +17 -2
  3. data/Gemfile +13 -2
  4. data/{LICENSE → MIT-LICENSE} +0 -0
  5. data/README.md +174 -117
  6. data/Rakefile +8 -3
  7. data/features/config_command_name.feature +12 -0
  8. data/features/config_merge_timeout.feature +3 -3
  9. data/features/config_profiles.feature +44 -0
  10. data/features/config_project_name.feature +2 -2
  11. data/features/cucumber_basic.feature +1 -1
  12. data/features/step_definitions/html_steps.rb +1 -1
  13. data/features/support/env.rb +23 -5
  14. data/gemfiles/multi_json_legacy.gemfile +12 -0
  15. data/gemfiles/multi_json_new.gemfile +12 -0
  16. data/lib/simplecov.rb +33 -25
  17. data/lib/simplecov/command_guesser.rb +6 -6
  18. data/lib/simplecov/configuration.rb +7 -2
  19. data/lib/simplecov/defaults.rb +9 -5
  20. data/lib/simplecov/file_list.rb +1 -1
  21. data/lib/simplecov/jruby16_fix.rb +43 -0
  22. data/lib/simplecov/no_defaults.rb +2 -0
  23. data/lib/simplecov/{adapters.rb → profiles.rb} +8 -8
  24. data/lib/simplecov/result.rb +10 -2
  25. data/lib/simplecov/source_file.rb +2 -3
  26. data/lib/simplecov/version.rb +1 -1
  27. data/simplecov.gemspec +8 -9
  28. data/test/faked_project/Gemfile +1 -1
  29. data/test/helper.rb +0 -1
  30. data/test/shoulda_macros.rb +0 -10
  31. data/test/test_1_8_fallbacks.rb +16 -18
  32. data/test/test_command_guesser.rb +13 -15
  33. data/test/test_deleted_source.rb +5 -7
  34. data/test/test_file_list.rb +15 -17
  35. data/test/test_filters.rb +56 -58
  36. data/test/test_merge_helpers.rb +73 -75
  37. data/test/test_result.rb +114 -116
  38. data/test/test_return_codes.rb +24 -26
  39. data/test/test_source_file.rb +75 -64
  40. data/test/test_source_file_line.rb +78 -82
  41. metadata +38 -86
  42. data/features/config_adapters.feature +0 -44
  43. data/gemfiles/multi_json-legacy.gemfile +0 -7
  44. data/gemfiles/multi_json-new.gemfile +0 -7
data/Rakefile CHANGED
@@ -21,7 +21,12 @@ Rake::TestTask.new(:test) do |test|
21
21
  test.warning = true
22
22
  end
23
23
 
24
- require 'cucumber/rake/task'
25
- Cucumber::Rake::Task.new
24
+ # Cucumber integration test suite is for impls that work with simplecov only - a.k.a. 1.9+
25
+ if '1.9+'.respond_to? :encoding
26
+ require 'cucumber/rake/task'
27
+ Cucumber::Rake::Task.new
28
+ task :default => [:test, :cucumber]
29
+ else
30
+ task :default => [:test]
31
+ end
26
32
 
27
- task :default => [:test, :cucumber]
@@ -31,3 +31,15 @@ Feature: Custom names for individual test suites
31
31
  | Dreck macht Speck |
32
32
  | I'm in UR Unitz |
33
33
 
34
+ Scenario: RSpec auto detection with spec/features
35
+ Given SimpleCov for RSpec is configured with:
36
+ """
37
+ require 'simplecov'
38
+ SimpleCov.start
39
+ """
40
+ And a file named "spec/features/foobar_spec.rb" with:
41
+ """
42
+ """
43
+ When I open the coverage report generated with `bundle exec rspec spec`
44
+ Then the report should be based upon:
45
+ | RSpec |
@@ -17,14 +17,14 @@ Feature:
17
17
  """
18
18
  require 'simplecov'
19
19
  SimpleCov.start do
20
- merge_timeout 1
20
+ merge_timeout 5
21
21
  end
22
22
  """
23
23
  Given SimpleCov for RSpec is configured with:
24
24
  """
25
25
  require 'simplecov'
26
26
  SimpleCov.start do
27
- merge_timeout 1
27
+ merge_timeout 5
28
28
  end
29
29
  """
30
30
 
@@ -32,7 +32,7 @@ Feature:
32
32
  Then the report should be based upon:
33
33
  | Unit Tests |
34
34
 
35
- When I wait for 2 seconds
35
+ When I wait for 5 seconds
36
36
  And I open the coverage report generated with `bundle exec rspec spec`
37
37
  Then the report should be based upon:
38
38
  | RSpec |
@@ -0,0 +1,44 @@
1
+ @test_unit @config @profiles
2
+ Feature:
3
+
4
+ In order to re-use SimpleCov settings across projects,
5
+ profiles can be defined that hold configuration settings
6
+ that can be loaded at once.
7
+
8
+ Background:
9
+ Given SimpleCov for Test/Unit is configured with:
10
+ """
11
+ require 'simplecov'
12
+ """
13
+
14
+ Scenario: Defining and using a custom profile
15
+ Given a file named ".simplecov" with:
16
+ """
17
+ SimpleCov.profiles.define 'custom_command' do
18
+ command_name "Profile Command"
19
+ end
20
+
21
+ SimpleCov.start do
22
+ load_profile 'test_frameworks'
23
+ load_profile 'custom_command'
24
+ end
25
+ """
26
+
27
+ When I open the coverage report generated with `bundle exec rake test`
28
+ Then I should see "4 files in total."
29
+ And I should see "using Profile Command" within "#footer"
30
+
31
+ Scenario: Using existing profile in custom profile and supplying profile to start command
32
+ Given a file named ".simplecov" with:
33
+ """
34
+ SimpleCov.profiles.define 'my_profile' do
35
+ load_profile 'test_frameworks'
36
+ command_name "My Profile"
37
+ end
38
+
39
+ SimpleCov.start 'my_profile'
40
+ """
41
+
42
+ When I open the coverage report generated with `bundle exec rake test`
43
+ Then I should see "4 files in total."
44
+ And I should see "using My Profile" within "#footer"
@@ -14,7 +14,7 @@ Feature:
14
14
  """
15
15
 
16
16
  When I open the coverage report generated with `bundle exec rake test`
17
- Then I should see "Code coverage for Project"
17
+ Then I should see "Code coverage for Project" within "title"
18
18
 
19
19
  Scenario: Custom name
20
20
  Given SimpleCov for Test/Unit is configured with:
@@ -24,4 +24,4 @@ Feature:
24
24
  """
25
25
 
26
26
  When I open the coverage report generated with `bundle exec rake test`
27
- Then I should see "Code coverage for Superfancy 2.0"
27
+ Then I should see "Code coverage for Superfancy 2.0" within "title"
@@ -19,7 +19,7 @@ Feature:
19
19
  And I should see the source files:
20
20
  | name | coverage |
21
21
  | lib/faked_project.rb | 100.0 % |
22
- | lib/faked_project/some_class.rb | 80.0 % |
22
+ | lib/faked_project/some_class.rb | 80.0 % |
23
23
  | lib/faked_project/framework_specific.rb | 75.0 % |
24
24
  | lib/faked_project/meta_magic.rb | 100.0 % |
25
25
  | features/step_definitions/my_steps.rb | 100.0 % |
@@ -35,7 +35,7 @@ Then /^I should see the source files:$/ do |table|
35
35
  expected_files.length.should == available_source_files.count
36
36
 
37
37
  # Find all filenames and their coverage present in coverage report
38
- files = available_source_files.map {|f| {"name" => f.find('h3').text, "coverage" => f.find('.header span').text} }
38
+ files = available_source_files.map {|f| {"name" => f.find('h3').text, "coverage" => f.find('h4 > span').text} }
39
39
 
40
40
  files.sort_by {|hsh| hsh["name"] }.should == expected_files.sort_by {|hsh| hsh["name"] }
41
41
  end
@@ -1,26 +1,44 @@
1
- unless RUBY_VERSION =~ /1\.9/
2
- $stderr.puts "Sorry, Cucumber features are only meant to run on Ruby 1.9 for now :("
1
+ unless '1.9'.respond_to?(:encoding)
2
+ $stderr.puts "Sorry, Cucumber features are only meant to run on Ruby 1.9+ :("
3
3
  exit 0
4
4
  end
5
5
 
6
6
  require 'bundler'
7
7
  Bundler.setup
8
8
  require 'aruba/cucumber'
9
+ require 'aruba/jruby' if RUBY_ENGINE == 'jruby'
9
10
  require 'capybara/cucumber'
11
+ require 'phantomjs/poltergeist'
10
12
 
11
13
  # Fake rack app for capybara that just returns the latest coverage report from aruba temp project dir
12
- Capybara.app = lambda {|env|
14
+ Capybara.app = lambda { |env|
15
+ request_path = env['REQUEST_PATH'] || '/'
16
+ request_path = '/index.html' if request_path == '/'
17
+
13
18
  [200, {'Content-Type' => 'text/html'},
14
- [File.read(File.join(File.dirname(__FILE__), '../../tmp/aruba/project', 'coverage/index.html'))]]
19
+ [File.read(File.join(File.dirname(__FILE__), '../../tmp/aruba/project/coverage', request_path))]]
15
20
  }
16
21
 
22
+ Capybara.default_driver = Capybara.javascript_driver = :poltergeist
23
+
17
24
  Before do
18
- @aruba_timeout_seconds = 20
25
+ # JRuby takes it's time... See https://github.com/cucumber/aruba/issues/134
26
+ @aruba_timeout_seconds = RUBY_ENGINE == 'jruby' ? 60 : 20
27
+
19
28
  this_dir = File.dirname(__FILE__)
29
+
20
30
  # Clean up and create blank state for fake project
21
31
  in_current_dir do
22
32
  FileUtils.rm_rf 'project'
23
33
  FileUtils.cp_r File.join(this_dir, '../../test/faked_project/'), 'project'
24
34
  end
35
+
25
36
  step 'I cd to "project"'
26
37
  end
38
+
39
+ # Workaround for https://github.com/cucumber/aruba/pull/125
40
+ Aruba.configure do |config|
41
+ config.before_cmd do
42
+ set_env('JRUBY_OPTS', '-X-C --1.9')
43
+ end
44
+ end
@@ -0,0 +1,12 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "aruba", "~> 0.5.1"
6
+ gem "capybara", "~> 2.0"
7
+ gem "poltergeist", "~> 1.1.0"
8
+ gem "phantomjs", "~> 1.8.1"
9
+ gem "cucumber", ">= 1.1.0"
10
+ gem "multi_json", "~> 1.0.0"
11
+
12
+ gemspec :path=>"../"
@@ -0,0 +1,12 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "aruba", "~> 0.5.1"
6
+ gem "capybara", "~> 2.0"
7
+ gem "poltergeist", "~> 1.1.0"
8
+ gem "phantomjs", "~> 1.8.1"
9
+ gem "cucumber", ">= 1.1.0"
10
+ gem "multi_json", ">= 1.3.4"
11
+
12
+ gemspec :path=>"../"
data/lib/simplecov.rb CHANGED
@@ -2,18 +2,15 @@
2
2
  # Code coverage for ruby 1.9. Please check out README for a full introduction.
3
3
  #
4
4
  module SimpleCov
5
- # Indicates invalid coverage data
6
- class CoverageDataError < StandardError; end;
7
-
8
5
  class << self
9
- attr_accessor :running#, :result # TODO: Remove result?
6
+ attr_accessor :running
10
7
 
11
8
  #
12
9
  # Sets up SimpleCov to run against your project.
13
- # You can optionally specify an adapter to use as well as configuration with a block:
10
+ # You can optionally specify a profile to use as well as configuration with a block:
14
11
  # SimpleCov.start
15
12
  # OR
16
- # SimpleCov.start 'rails' # using rails adapter
13
+ # SimpleCov.start 'rails' # using rails profile
17
14
  # OR
18
15
  # SimpleCov.start do
19
16
  # add_filter 'test'
@@ -25,15 +22,17 @@ module SimpleCov
25
22
  #
26
23
  # Please check out the RDoc for SimpleCov::Configuration to find about available config options
27
24
  #
28
- def start(adapter=nil, &block)
29
- return false unless SimpleCov.usable?
30
-
31
- require 'coverage'
32
- load_adapter(adapter) unless adapter.nil?
33
- Coverage.start
34
- configure(&block) if block_given?
35
- @result = nil
36
- self.running = true
25
+ def start(profile=nil, &block)
26
+ if SimpleCov.usable?
27
+ load_profile(profile) if profile
28
+ configure(&block) if block_given?
29
+ @result = nil
30
+ self.running = true
31
+ Coverage.start
32
+ else
33
+ warn "WARNING: SimpleCov is activated, but you're not running Ruby 1.9+ - no coverage analysis will happen"
34
+ false
35
+ end
37
36
  end
38
37
 
39
38
  #
@@ -90,22 +89,31 @@ module SimpleCov
90
89
  end
91
90
 
92
91
  #
93
- # Applies the adapter of given name on SimpleCov configuration
92
+ # Applies the profile of given name on SimpleCov configuration
94
93
  #
94
+ def load_profile(name)
95
+ profiles.load(name)
96
+ end
97
+
95
98
  def load_adapter(name)
96
- adapters.load(name)
99
+ warn "method load_adapter is deprecated. use load_profile instead"
100
+ load_profile(name)
97
101
  end
98
102
 
99
103
  #
100
- # Checks whether we're on a proper version of ruby (1.9+) and returns false if this is not the case,
101
- # also printing an appropriate warning
104
+ # Checks whether we're on a proper version of Ruby (likely 1.9+) which
105
+ # provides coverage support
102
106
  #
103
107
  def usable?
104
- unless "1.9".respond_to?(:encoding)
105
- warn "WARNING: SimpleCov is activated, but you're not running Ruby 1.9+ - no coverage analysis will happen"
106
- return false
108
+ return @usable if defined? @usable and !@usable.nil?
109
+
110
+ @usable = begin
111
+ require 'coverage'
112
+ require 'simplecov/jruby16_fix'
113
+ true
114
+ rescue LoadError
115
+ false
107
116
  end
108
- true
109
117
  end
110
118
  end
111
119
  end
@@ -115,7 +123,7 @@ require 'simplecov/configuration'
115
123
  SimpleCov.send :extend, SimpleCov::Configuration
116
124
  require 'simplecov/exit_codes'
117
125
  require 'simplecov/json'
118
- require 'simplecov/adapters'
126
+ require 'simplecov/profiles'
119
127
  require 'simplecov/source_file'
120
128
  require 'simplecov/file_list'
121
129
  require 'simplecov/result'
@@ -128,7 +136,7 @@ require 'simplecov/command_guesser'
128
136
  require 'simplecov/version'
129
137
 
130
138
  # Load default config
131
- require 'simplecov/defaults'
139
+ require 'simplecov/defaults' unless ENV['SIMPLECOV_NO_DEFAULTS']
132
140
 
133
141
  # Load Rails integration (only for Rails 3, see #113)
134
142
  require 'simplecov/railtie' if defined? Rails::Railtie
@@ -18,16 +18,16 @@ module SimpleCov::CommandGuesser
18
18
 
19
19
  def from_command_line_options
20
20
  case original_run_command
21
- when /#{'test/functional/'}/
21
+ when /test\/functional\//, /test\/{.*?functional.*?}\//
22
22
  "Functional Tests"
23
- when /#{'test/integration/'}/
23
+ when /test\/integration\//
24
24
  "Integration Tests"
25
- when /#{'test/'}/
25
+ when /test\//
26
26
  "Unit Tests"
27
- when /cucumber/, /features/
28
- "Cucumber Features"
29
27
  when /spec/
30
28
  "RSpec"
29
+ when /cucumber/, /features/
30
+ "Cucumber Features"
31
31
  else
32
32
  nil
33
33
  end
@@ -46,4 +46,4 @@ module SimpleCov::CommandGuesser
46
46
  end
47
47
  end
48
48
  end
49
- end
49
+ end
@@ -94,10 +94,15 @@ module SimpleCov::Configuration
94
94
  end
95
95
 
96
96
  #
97
- # Returns the hash of available adapters
97
+ # Returns the hash of available profiles
98
98
  #
99
+ def profiles
100
+ @profiles ||= SimpleCov::Profiles.new
101
+ end
102
+
99
103
  def adapters
100
- @adapters ||= SimpleCov::Adapters.new
104
+ warn "method adapters is deprecated. use profiles instead"
105
+ profiles
101
106
  end
102
107
 
103
108
  #
@@ -1,22 +1,22 @@
1
1
  # Load default formatter gem
2
2
  require 'simplecov-html'
3
3
 
4
- SimpleCov.adapters.define 'root_filter' do
4
+ SimpleCov.profiles.define 'root_filter' do
5
5
  # Exclude all files outside of simplecov root
6
6
  add_filter do |src|
7
7
  !(src.filename =~ /^#{SimpleCov.root}/)
8
8
  end
9
9
  end
10
10
 
11
- SimpleCov.adapters.define 'test_frameworks' do
11
+ SimpleCov.profiles.define 'test_frameworks' do
12
12
  add_filter '/test/'
13
13
  add_filter '/features/'
14
14
  add_filter '/spec/'
15
15
  add_filter '/autotest/'
16
16
  end
17
17
 
18
- SimpleCov.adapters.define 'rails' do
19
- load_adapter 'test_frameworks'
18
+ SimpleCov.profiles.define 'rails' do
19
+ load_profile 'test_frameworks'
20
20
 
21
21
  add_filter '/config/'
22
22
  add_filter '/db/'
@@ -34,7 +34,7 @@ end
34
34
  SimpleCov.configure do
35
35
  formatter SimpleCov::Formatter::HTMLFormatter
36
36
  # Exclude files outside of SimpleCov.root
37
- load_adapter 'root_filter'
37
+ load_profile 'root_filter'
38
38
  end
39
39
 
40
40
  # Gotta stash this a-s-a-p, see the CommandGuesser class and i.e. #110 for further info
@@ -81,6 +81,10 @@ at_exit do
81
81
  exit @exit_status if @exit_status # Force exit with stored status (see github issue #5)
82
82
  end
83
83
 
84
+ # Autoload config from ~/.simplecov if present
85
+ global_config_path = File.join(File.expand_path("~"), '.simplecov')
86
+ load global_config_path if File.exist?(global_config_path)
87
+
84
88
  # Autoload config from .simplecov if present
85
89
  config_path = File.join(SimpleCov.root, '.simplecov')
86
90
  load config_path if File.exist?(config_path)
@@ -39,6 +39,6 @@ class SimpleCov::FileList < Array
39
39
  # Computes the strength (hits / line) based upon lines covered and lines missed
40
40
  def covered_strength
41
41
  return 0 if empty? or lines_of_code == 0
42
- map {|f| f.covered_strength }.inject(&:+) / size
42
+ map {|f| f.covered_strength }.inject(&:+).to_f / size
43
43
  end
44
44
  end
@@ -0,0 +1,43 @@
1
+ if defined?(JRUBY_VERSION) && JRUBY_VERSION.to_f < 1.7
2
+ require 'jruby'
3
+ java_import 'org.jruby.ast.NodeType'
4
+
5
+ # Coverage for JRuby < 1.7.0 does not work correctly
6
+ #
7
+ # - does not distinguish lines that cannot be executed
8
+ # - does (partial) coverage for files loaded before `Coverage.start`.
9
+ # - does not expand a path like `lib/../spec` to `spec`.
10
+ #
11
+ # This monkey patches Coverage to address those issues
12
+ module Coverage
13
+ class << self
14
+ alias __broken_result__ result
15
+
16
+ def result
17
+ fixed = {}
18
+ __broken_result__.each do |path, executed_lines|
19
+ covered_lines = executed_lines.dup
20
+
21
+ process = lambda do |node|
22
+ if node.node_type == NodeType::NEWLINENODE
23
+ pos = node.position
24
+ covered_lines[pos.line] ||= 0
25
+ end
26
+ node.child_nodes.each(&process)
27
+ end
28
+
29
+ begin
30
+ process[JRuby.parse(File.read(path), path)]
31
+ rescue => e
32
+ end
33
+
34
+ if (first = covered_lines.detect { |x| x }) && first > 0
35
+ fixed[File.expand_path(path)] = covered_lines
36
+ end
37
+ end
38
+
39
+ fixed
40
+ end
41
+ end
42
+ end
43
+ end