simplecov 0.3.0

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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,24 @@
1
+ .rvmrc
2
+ .bundle
3
+
4
+ ## MAC OS
5
+ .DS_Store
6
+
7
+ ## TEXTMATE
8
+ *.tmproj
9
+ tmtags
10
+
11
+ ## EMACS
12
+ *~
13
+ \#*
14
+ .\#*
15
+
16
+ ## VIM
17
+ *.swp
18
+
19
+ ## PROJECT::GENERAL
20
+ coverage
21
+ rdoc
22
+ pkg
23
+
24
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Christoph Olszowka
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,43 @@
1
+ = simplecov
2
+
3
+ SimpleCov is a code coverage analysis tool for Ruby 1.9. It makes use of Ruby's built-in Coverage library, wrapping
4
+ it's results in a object-oriented manner. It also adds some sugar like filtering (so the coverage of used gems is not
5
+ taken into account) and grouping (to check coverage on your Rails models for instance).
6
+
7
+ Though it ships with a basic formatter, it isn't particularily useful by itself, so you're going to need a dedicated
8
+ formatter library - check out simple_cov-html for that!
9
+
10
+ Thanks to Aaron Patterson (http://engineering.attinteractive.com/2010/08/code-coverage-in-ruby-1-9/) for the original idea
11
+ for this!
12
+
13
+ == Example config for Rails 3 (using HTML formatter)
14
+
15
+ Update your Gemfile with this and do a bundle install:
16
+ group :test do
17
+ gem 'simplecov', '>= 0.2.0'
18
+ gem 'simplecov-html', '>= 0.2.0'
19
+ end
20
+
21
+ Then, add the following to your Rails test/test_helper.rb (right at the top, line 00):
22
+
23
+ require 'simple_cov'
24
+ SimpleCov.start 'rails'
25
+
26
+ Now, when running rake test you'll get a coverage/ folder inside your app's root where you can browse your code coverage.
27
+
28
+ == TODO
29
+ * Improve on tests (integration tests)
30
+
31
+ == Note on Patches/Pull Requests
32
+
33
+ * Fork the project.
34
+ * Make your feature addition or bug fix.
35
+ * Add tests for it. This is important so I don't break it in a
36
+ future version unintentionally.
37
+ * Commit, do not mess with rakefile, version, or history.
38
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
39
+ * Send me a pull request. Bonus points for topic branches.
40
+
41
+ == Copyright
42
+
43
+ Copyright (c) 2010 Christoph Olszowka. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "simplecov"
8
+ gem.summary = %Q{Code coverage for Ruby 1.9}
9
+ gem.description = %Q{Code coverage for Ruby 1.9}
10
+ gem.email = "christoph at olszowka.de"
11
+ gem.homepage = "http://github.com/colszowka/simplecov"
12
+ gem.authors = ["Christoph Olszowka"]
13
+ gem.add_development_dependency "shoulda", "= 2.10.3"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/test_*.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+ task :test => :check_dependencies
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "simplecov #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.0
data/lib/simplecov.rb ADDED
@@ -0,0 +1,107 @@
1
+ module SimpleCov
2
+ class CoverageDataError < StandardError; end;
3
+ VERSION = File.read(File.join(File.dirname(__FILE__), '../VERSION'))
4
+
5
+ class << self
6
+ attr_accessor :running, :result # TODO: Remove result?
7
+
8
+ #
9
+ # Sets up SimpleCov to run against your project.
10
+ #
11
+ # TODO: Explain config! Add default adapters!
12
+ #
13
+ def start(adapter=nil, &block)
14
+ unless "1.9".respond_to?(:encoding)
15
+ warn "WARNING: SimpleCov is activated, but you're not running Ruby 1.9 - no coverage analysis will happen"
16
+ return false
17
+ end
18
+ require 'coverage'
19
+ load_adapter(adapter) unless adapter.nil?
20
+ Coverage.start
21
+ configure(&block) if block_given?
22
+ @result = nil
23
+ self.running = true
24
+ end
25
+
26
+ #
27
+ # Returns the result for the currntly runnig coverage run
28
+ #
29
+ def result
30
+ @result ||= SimpleCov::Result.new(Coverage.result) if running
31
+ # If we're using merging of results, store the current result
32
+ # first, then merge the results and return them
33
+ if use_merging
34
+ SimpleCov::ResultMerger.store_result(@result) if @result
35
+ return SimpleCov::ResultMerger.merged_result
36
+ else
37
+ return @result
38
+ end
39
+ ensure
40
+ self.running = false
41
+ end
42
+
43
+ #
44
+ # Returns the project name - currently assuming the last dirname in
45
+ # the SimpleCov.root is this
46
+ #
47
+ def project_name
48
+ File.basename(root.split('/').last).capitalize.gsub('_', ' ')
49
+ end
50
+
51
+ #
52
+ # Applies the configured filters to the given array of SimpleCov::SourceFile items
53
+ #
54
+ def filtered(files)
55
+ result = files.clone
56
+ filters.each do |filter|
57
+ result = result.select {|source_file| filter.passes?(source_file) }
58
+ end
59
+ result
60
+ end
61
+
62
+ #
63
+ # Applies the configured groups to the given array of SimpleCov::SourceFile items
64
+ #
65
+ def grouped(files)
66
+ grouped = {}
67
+ grouped_files = []
68
+ groups.each do |name, filter|
69
+ grouped[name] = files.select {|source_file| !filter.passes?(source_file)}
70
+ grouped_files += grouped[name]
71
+ end
72
+ if groups.length > 0 and (other_files = files.reject {|source_file| grouped_files.include?(source_file)}).length > 0
73
+ grouped["Ungrouped"] = other_files
74
+ end
75
+ grouped
76
+ end
77
+
78
+ #
79
+ # Applies the adapter of given name on SimpleCov configuration
80
+ #
81
+ def load_adapter(name)
82
+ adapters.load(name)
83
+ end
84
+ end
85
+ end
86
+
87
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__)))
88
+ require 'simplecov/configuration'
89
+ SimpleCov.send :extend, SimpleCov::Configuration
90
+ require 'simplecov/adapters'
91
+ require 'simplecov/source_file'
92
+ require 'simplecov/result'
93
+ require 'simplecov/filter'
94
+ require 'simplecov/formatter'
95
+ require 'simplecov/merge_helpers'
96
+ require 'simplecov/result_merger'
97
+
98
+ # Default configuration
99
+ SimpleCov.configure do
100
+ formatter SimpleCov::Formatter::SimpleFormatter
101
+ # Exclude files outside of SimpleCov.root
102
+ load_adapter 'root_filter'
103
+ end
104
+
105
+ at_exit do
106
+ SimpleCov.at_exit.call
107
+ end
@@ -0,0 +1,47 @@
1
+ #
2
+ # Adaptars are glorified SimpleCov configuration procs that can be easily
3
+ # loaded using SimpleCov.start :rails and defined using
4
+ # SimpleCov.adapters.define :foo do
5
+ # # SimpleCov configuration here, same as in
6
+ # end
7
+ #
8
+ class SimpleCov::Adapters < Hash
9
+ #
10
+ # Define a SimpleCov adapter:
11
+ # SimpleCov.adapters.define 'rails' do
12
+ # # Same as SimpleCov.configure do .. here
13
+ # end
14
+ #
15
+ def define(name, &blk)
16
+ name = name.to_sym
17
+ raise "SimpleCov Adapter '#{name}' is already defined" unless self[name].nil?
18
+ self[name] = blk
19
+ end
20
+
21
+ #
22
+ # Applies the adapter of given name
23
+ #
24
+ def load(name)
25
+ name = name.to_sym
26
+ raise "Could not find SimpleCov Adapter called '#{name}'" unless has_key?(name)
27
+ SimpleCov.configure(&self[name])
28
+ end
29
+ end
30
+
31
+ SimpleCov.adapters.define 'root_filter' do
32
+ # Exclude all files outside of simplecov root
33
+ add_filter do |src|
34
+ !(src.filename =~ /^#{SimpleCov.root}/)
35
+ end
36
+ end
37
+
38
+ SimpleCov.adapters.define 'rails' do
39
+ add_filter '/test/'
40
+ add_filter '/config/'
41
+
42
+ add_group 'Controllers', 'app/controllers'
43
+ add_group 'Models', 'app/models'
44
+ add_group 'Helpers', 'app/helpers'
45
+ add_group 'Libraries', 'lib'
46
+ add_group 'Plugins', 'vendor/plugins'
47
+ end
@@ -0,0 +1,174 @@
1
+ #
2
+ # Bundles the configuration options used for SimpleCov. All methods
3
+ # defined here are usable from SimpleCov directly. Please check out
4
+ # SimpleCov documentation for further info.
5
+ #
6
+ module SimpleCov::Configuration
7
+ attr_writer :filters, :groups, :formatter
8
+
9
+ #
10
+ # The root for the project. This defaults to the
11
+ # current working directory.
12
+ #
13
+ # Configure with SimpleCov.root('/my/project/path')
14
+ #
15
+ def root(root=nil)
16
+ return @root if @root and root.nil?
17
+ @root = File.expand_path(root || Dir.getwd)
18
+ end
19
+
20
+ #
21
+ # The name of the output and cache directory. Defaults to 'coverage'
22
+ #
23
+ # Configure with SimpleCov.coverage_dir('cov')
24
+ #
25
+ def coverage_dir(dir=nil)
26
+ return @coverage_dir if @coverage_dir and dir.nil?
27
+ @coverage_dir = (dir || 'coverage')
28
+ end
29
+
30
+ #
31
+ # Returns the full path to the output directory using SimpleCov.root
32
+ # and SimpleCov.coverage_dir, so you can adjust this by configuring those
33
+ # values. Will create the directory if it's missing
34
+ #
35
+ def coverage_path
36
+ coverage_path = File.join(root, coverage_dir)
37
+ system "mkdir -p '#{coverage_path}'"
38
+ coverage_path
39
+ end
40
+
41
+ #
42
+ # Returns the list of configured filters. Add filters using SimpleCov.add_filter.
43
+ #
44
+ def filters
45
+ @filters ||= []
46
+ end
47
+
48
+ # The name of the command currently running. It is used for result merging and defaults
49
+ # to the command line arguments the current test suite is running on.
50
+ # You can specify it manually with SimpleCov.command_name("test:units")
51
+ def command_name(name=nil)
52
+ @name ||= (name.nil? ? ARGV.join(" ") : name)
53
+ end
54
+
55
+ #
56
+ # Gets or sets the configured formatter.
57
+ #
58
+ # Configure with: SimpleCov.formatter(SimpleCov::Formatter::SimpleFormatter)
59
+ #
60
+ def formatter(formatter=nil)
61
+ return @formatter if @formatter and formatter.nil?
62
+ @formatter = formatter
63
+ raise "No formatter configured. Please specify a formatter using SimpleCov.formatter = SimpleCov::Formatter::SimpleFormatter" unless @formatter
64
+ @formatter
65
+ end
66
+
67
+ #
68
+ # Returns the configured groups. Add groups using SimpleCov.add_group
69
+ #
70
+ def groups
71
+ @groups ||= {}
72
+ end
73
+
74
+ #
75
+ # Returns the hash of available adapters
76
+ #
77
+ def adapters
78
+ @adapters ||= SimpleCov::Adapters.new
79
+ end
80
+
81
+ #
82
+ # Configure SimpleCov using a block:
83
+ #
84
+ # SimpleCov.configure do
85
+ # add_filter 'foobar'
86
+ # end
87
+ #
88
+ # This is equivalent to SimpleCov.add_filter 'foobar' and thus makes it easier to set a lot of configure
89
+ # options.
90
+ #
91
+ def configure(&block)
92
+ instance_exec(&block)
93
+ end
94
+
95
+ #
96
+ # Gets or sets the behavior to process coverage results.
97
+ #
98
+ # By default, it will call SimpleCov.result.format!
99
+ #
100
+ # Configure with:
101
+ # SimpleCov.at_exit do
102
+ # puts "Coverage done"
103
+ # SimpleCov.result.format!
104
+ # end
105
+ #
106
+ def at_exit(&block)
107
+ return Proc.new {} unless running or block_given?
108
+ @at_exit = block if block_given?
109
+ @at_exit ||= Proc.new { SimpleCov.result.format! }
110
+ end
111
+
112
+ #
113
+ # Defines whether to use result merging so all your test suites (test:units, test:functionals, cucumber, ...)
114
+ # are joined and combined into a single coverage report
115
+ #
116
+ def use_merging(use=nil)
117
+ @use_merging = use unless use.nil? # Set if param given
118
+ @use_merging = true if @use_merging != false
119
+ end
120
+
121
+ #
122
+ # Defines them maximum age (in seconds) of a resultset to still be included in merged results.
123
+ # i.e. If you run cucumber features, then later rake test, if the stored cucumber resultset is
124
+ # more seconds ago than specified here, it won't be taken into account when merging (and is also
125
+ # purged from the resultset cache)
126
+ #
127
+ # Of course, this only applies when merging is active (e.g. SimpleCov.use_merging is not false!)
128
+ #
129
+ # Default is 600 seconds (10 minutes)
130
+ #
131
+ # Configure with SimpleCov.merge_timeout(3600) # 1hr
132
+ #
133
+ def merge_timeout(seconds=nil)
134
+ @merge_timeout = seconds if !seconds.nil? and seconds.kind_of?(Fixnum)
135
+ @merge_timeout ||= 600
136
+ end
137
+
138
+ #
139
+ # Add a filter to the processing chain.
140
+ # There are three ways to define a filter:
141
+ #
142
+ # * as a String that will then be matched against all source files' file paths,
143
+ # SimpleCov.add_filter 'app/models' # will reject all your models
144
+ # * as a block which will be passed the source file in question and should either
145
+ # return a true or false value, depending on whether the file should be removed
146
+ # SimpleCov.add_filter do |src_file|
147
+ # File.basename(src_file.filename) == 'environment.rb'
148
+ # end # Will exclude environment.rb files from the results
149
+ # * as an instance of a subclass of SimpleCov::Filter. See the documentation there
150
+ # on how to define your own filter classes
151
+ #
152
+ def add_filter(filter_argument=nil, &filter_proc)
153
+ filters << parse_filter(filter_argument, &filter_proc)
154
+ end
155
+
156
+ def add_group(group_name, filter_argument=nil, &filter_proc)
157
+ groups[group_name] = parse_filter(filter_argument, &filter_proc)
158
+ end
159
+
160
+ #
161
+ # The actal filter processor. Not meant for direct use
162
+ #
163
+ def parse_filter(filter_argument=nil, &filter_proc)
164
+ if filter_argument.kind_of?(SimpleCov::Filter)
165
+ filter_argument
166
+ elsif filter_argument.kind_of?(String)
167
+ SimpleCov::StringFilter.new(filter_argument)
168
+ elsif filter_proc
169
+ SimpleCov::BlockFilter.new(filter_proc)
170
+ else
171
+ raise ArgumentError, "Please specify either a string or a block to filter with"
172
+ end
173
+ end
174
+ end