simplecov 0.3.0 → 0.3.1

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/README.rdoc CHANGED
@@ -1,30 +1,257 @@
1
1
  = simplecov
2
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).
3
+ SimpleCov is a code coverage analysis tool for Ruby 1.9. It uses 1.9's built-in Coverage library to gather code
4
+ coverage data, but makes processing it's results much easier by providing a clean API to filter, group, merge, format
5
+ and display those results, thus giving you a complete code coverage suite with just a couple lines of code.
6
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!
7
+ In most cases, you'll want overall coverage results for your projects, including all types of tests, cucumber features
8
+ etc. Simplecov automatically takes care of this by caching and then merging results when generating reports, so your
9
+ coverage report gives you a more accurate report on the blank spots in your test coverage.
9
10
 
10
- Thanks to Aaron Patterson (http://engineering.attinteractive.com/2010/08/code-coverage-in-ruby-1-9/) for the original idea
11
- for this!
11
+ Though a very simple formatter for printing the coverage results comes bundled with the simplecov gem, this is more
12
+ for explaining the basic usage of formatters if you want to build your own. To get a pretty HTML-page with your results,
13
+ you will want to use the simplecov-html gem (http://github.com/colszowka/simplecov-html).
12
14
 
13
- == Example config for Rails 3 (using HTML formatter)
15
+ == Basic usage
14
16
 
15
17
  Update your Gemfile with this and do a bundle install:
16
18
  group :test do
17
- gem 'simplecov', '>= 0.2.0'
18
- gem 'simplecov-html', '>= 0.2.0'
19
+ gem 'simplecov-html', '>= 0.3.0' # Will install simplecov as a dependency
19
20
  end
20
21
 
21
22
  Then, add the following to your Rails test/test_helper.rb (right at the top, line 00):
22
23
 
23
- require 'simple_cov'
24
+ require 'simplecov-html'
24
25
  SimpleCov.start 'rails'
25
26
 
26
27
  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
 
29
+ == Configuration
30
+
31
+ Configuration settings can be applied in three formats.
32
+
33
+ The 'direct' way:
34
+
35
+ SimpleCov.some_config_option 'foo'
36
+
37
+ Using a block:
38
+
39
+ SimpleCov.configure do
40
+ some_config_option 'foo'
41
+ end
42
+
43
+ Using a block and automatically starting the coverage:
44
+
45
+ SimpleCov.start do
46
+ some_config_option 'foo'
47
+ end
48
+
49
+ Most times, you'll want to use the latter, so loading and setting up simplecov is in one place at the top of your test helper.
50
+
51
+ == Filters
52
+
53
+ Filters can be used to remove selected files from your coverage data. By default, a filter is applied that removes all files
54
+ OUTSIDE of your project's root directory - otherwise you'd end up with a billion of coverage reports for source files in the
55
+ gems you are using.
56
+
57
+ Of course you can define your own to remove things like configuration files, tests or whatever you don't need in your coverage
58
+ report.
59
+
60
+ === Defining custom filters
61
+
62
+ You can currently define a filter using either a String (that will then be Regexp-matched against each source file's path),
63
+ a block or by passing in your own Filter class.
64
+
65
+ ==== String filter
66
+
67
+ SimpleCov.start do
68
+ add_filter "/test/"
69
+ end
70
+
71
+ This simple string filter will remove all files that match "/test/" in their path.
72
+
73
+ ==== Block filter
74
+
75
+ SimpleCov.start do
76
+ add_filter do |source_file|
77
+ source_file.lines.count < 5
78
+ end
79
+ end
80
+
81
+ Block filters receive a SimpleCov::SourceFile instance and expect your block to return either true (if the file is to be removed
82
+ from the result) or false (if the result should be kept). Please check out the RDoc for SimpleCov::SourceFile to learn about the
83
+ methods available to you. In the above example, the filter will remove all files that have less then 5 lines of code.
84
+
85
+ ==== Custom filter class
86
+
87
+ class LineFilter < SimpleCov::Filter
88
+ def passes?(source_file)
89
+ source_file.lines.count < filter_argument
90
+ end
91
+ end
92
+
93
+ SimpleCov.add_filter LineFilter.new(5)
94
+
95
+ Defining your own filters is pretty easy: Just inherit from SimpleCov::Filter and define a method 'passes?(source_file)'. When running
96
+ the filter, a true return value from this method will result in the removal of the given source_file. The filter_argument method
97
+ is being set in the SimpleCov::Filter initialize method and thus is set to 5 in this example.
98
+
99
+ == Groups
100
+
101
+ You can separate your source files into groups. For example, in a rails app, you'll want to have separate listings for
102
+ Models, Controllers, Helpers, Libs and Plugins. Group definition works similar to Filters (and indeed also accepts custom
103
+ filter classes), but source files end up in a group when the filter passes (returns true), as opposed to filtering results,
104
+ which exclude files from results when the filter results in a true value.
105
+
106
+ Add your groups with:
107
+
108
+ SimpleCov.start do
109
+ add_group "Models", "app/models"
110
+ add_group "Controllers", "app/controllers"
111
+ add_group "Long files" do |src_file|
112
+ src_file.lines.count > 100
113
+ end
114
+ add_group "Short files", LineFilter.new(5) # Using the LineFilter class defined in Filters section above
115
+ end
116
+
117
+ == Merging results
118
+
119
+ Normally, you want to have your coverage analyzed across ALL of your test suites, right?
120
+
121
+ Simplecov automatically caches coverage results in your (coverage_path)/resultset.yml. Those results will then
122
+ be automatically merged when generating the result, so when coverage is set up properly for cucumber and your
123
+ unit / functional / integration tests, all of those test suites will be taken into account when building the
124
+ coverage report.
125
+
126
+ There are two things to note here though:
127
+
128
+ === Test suite names
129
+
130
+ First, simplecov by itself does not really know about "test suites" and thus makes a guess based upon the command
131
+ line arguments it is currently running on. This works fine, though the test suites used for your coverage report
132
+ won't be easy to recognize.
133
+
134
+ Thus, if you want nicely labeled test suites, you have to give Simplecov a cue what the name of the currently running
135
+ test suite is. You can do so by specifying SimpleCov.command_name in one test file that is part of your specific suite.
136
+
137
+ So, in order to get proper suite names in a Rails app (yeah, sorry for being Rails biased, but everyone knows what
138
+ the structure of those projects is. You can apply this accordingly to the RSpecs for your Outlook-WebDAV-Calendar-Sync gem),
139
+ you could do something like this:
140
+
141
+ # test/unit/some_test.rb
142
+ SimpleCov.command_name 'Unit Tests'
143
+
144
+ # test/functionals/some_controller_test.rb
145
+ SimpleCov.command_name "Functional Tests"
146
+
147
+ # test/integration/some_integration_test.rb
148
+ SimpleCov.command_name "Integration Tests"
149
+
150
+ # features/steps/web_steps.rb
151
+ SimpleCov.command_name "Cucumber Features"
152
+
153
+ Note that this has only to be invoked ONCE PER TEST SUITE, so even if you have 200 unit test files, specifying it in
154
+ some_test.rb is fair enough.
155
+
156
+ simplecov-html prints the used test suites in the footer of the generated coverage report.
157
+
158
+ === Timeout for merge
159
+
160
+ Of course, your cached coverage data is likely to become invalid at some point. Thus, result sets that are older than
161
+ SimpleCov.merge_timeout will not be used any more. By default, the timeout is 600 seconds (10 minutes), and you can
162
+ raise (or lower) it by specifying SimpleCov.merge_timeout 3600 (1 hour), or, inside a configure/start block, with
163
+ just "merge_timeout 3600".
164
+
165
+ You can deactivate merging altogether with "SimpleCov.use_merging false".
166
+
167
+ == Adapters
168
+
169
+ By default, Simplecov's only config assumption is that you only want coverage reports for files inside your project
170
+ root. To save you from repetitive configuration, you can use predefined blocks of configuration, called 'adapters',
171
+ or define your own.
172
+
173
+ You can then pass the name of the adapter to be used as the first argument to SimpleCov.start. For example, simplecov
174
+ comes bundled with a 'rails' adapter. It looks somewhat like this:
175
+
176
+ SimpleCov.adapters.define 'rails' do
177
+ add_filter '/test/'
178
+ add_filter '/config/'
179
+
180
+ add_group 'Controllers', 'app/controllers'
181
+ add_group 'Models', 'app/models'
182
+ add_group 'Helpers', 'app/helpers'
183
+ add_group 'Libraries', 'lib'
184
+ add_group 'Plugins', 'vendor/plugins'
185
+ end
186
+
187
+ As you can see, it's just a glorified SimpleCov.configure block. In your test_helper.rb, launch simplecov with:
188
+
189
+ SimpleCov.start 'rails'
190
+
191
+ OR
192
+
193
+ SimpleCov.start 'rails' do
194
+ # additional config here
195
+ end
196
+
197
+ === Custom adapters
198
+
199
+ You can load additional adapters with the SimpleCov.load_adapter('xyz') method. This allows you to build upon an existing
200
+ adapter and customize it so you can reuse it in unit tests and cucumber features, for example.
201
+
202
+ # lib/simplecov_custom_adapter.rb
203
+ require 'simplecov'
204
+ SimpleCov.adapters.define 'myadapter' do
205
+ load_adapter 'rails'
206
+ add_filter 'vendor' # Don't include vendored stuff
207
+ end
208
+
209
+ # features/support/env.rb
210
+ require 'simplecov_custom_adapter'
211
+ SimpleCov.start 'myadapter'
212
+
213
+ # test/test_helper.rb
214
+ require 'simplecov_custom_adapter'
215
+ SimpleCov.start 'myadapter'
216
+
217
+ == Customizing exit behaviour
218
+
219
+ You can define what simplecov should do when your test suite finishes by customizing the at_exit hook:
220
+
221
+ SimpleCov.at_exit do
222
+ SimpleCov.result.format!
223
+ end
224
+
225
+ Above is the default behaviour. Do whatever you like instead!
226
+
227
+ == Using your own formatter
228
+
229
+ You can use your own formatter with:
230
+
231
+ SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter
232
+
233
+ When calling SimpleCov.result.format!, it will be invoked with SimpleCov::Formatter::YourFormatter.new.format(result), "result"
234
+ being an instance of SimpleCov::Result. Do whatever your wish with that!
235
+
236
+ == Configuration options
237
+
238
+ === SimpleCov.root '/some/path/to/coverage'
239
+
240
+ The root directory for the project coverage is being generated for. This defaults to the current working directory
241
+ and should be just fine. Note that by default, all files outside of root will be filtered and thus not included in your
242
+ coverage report, so you'll probably rarely want to adjust this setting other than specifying an absolute path here.
243
+
244
+ === SimpleCov.coverage_dir 'coverage'
245
+
246
+ The name of the subdirectory of root that coverage will be generated to. Defaults to 'coverage'.
247
+
248
+ === ...TODO...
249
+
250
+ == Kudos
251
+
252
+ Thanks to Aaron Patterson (http://engineering.attinteractive.com/2010/08/code-coverage-in-ruby-1-9/) for the original idea
253
+ for this!
254
+
28
255
  == TODO
29
256
  * Improve on tests (integration tests)
30
257
 
data/Rakefile CHANGED
@@ -25,19 +25,6 @@ Rake::TestTask.new(:test) do |test|
25
25
  test.verbose = true
26
26
  end
27
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
28
  task :test => :check_dependencies
42
29
 
43
30
  task :default => :test
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.3.1
data/lib/simplecov.rb CHANGED
@@ -1,14 +1,32 @@
1
+ #
2
+ # Code coverage for ruby 1.9. Please check out README for a full introduction.
3
+ #
1
4
  module SimpleCov
5
+ # Indicates invalid coverage data
2
6
  class CoverageDataError < StandardError; end;
7
+
8
+ # The version of the simplecov gem
3
9
  VERSION = File.read(File.join(File.dirname(__FILE__), '../VERSION'))
4
10
 
5
11
  class << self
6
- attr_accessor :running, :result # TODO: Remove result?
12
+ attr_accessor :running#, :result # TODO: Remove result?
7
13
 
8
14
  #
9
15
  # Sets up SimpleCov to run against your project.
16
+ # You can optionally specify an adapter to use as well as configuration with a block:
17
+ # SimpleCov.start
18
+ # OR
19
+ # SimpleCov.start 'rails' # using rails adapter
20
+ # OR
21
+ # SimpleCov.start do
22
+ # add_filter 'test'
23
+ # end
24
+ # OR
25
+ # SimpleCov.start 'rails' do
26
+ # add_filter 'test'
27
+ # end
10
28
  #
11
- # TODO: Explain config! Add default adapters!
29
+ # Please check out the RDoc for SimpleCov::Configuration to find about available config options
12
30
  #
13
31
  def start(adapter=nil, &block)
14
32
  unless "1.9".respond_to?(:encoding)
@@ -24,12 +42,13 @@ module SimpleCov
24
42
  end
25
43
 
26
44
  #
27
- # Returns the result for the currntly runnig coverage run
45
+ # Returns the result for the current coverage run, merging it across test suites
46
+ # from cache using SimpleCov::ResultMerger if use_merging is activated (default)
28
47
  #
29
48
  def result
30
49
  @result ||= SimpleCov::Result.new(Coverage.result) if running
31
50
  # If we're using merging of results, store the current result
32
- # first, then merge the results and return them
51
+ # first, then merge the results and return those
33
52
  if use_merging
34
53
  SimpleCov::ResultMerger.store_result(@result) if @result
35
54
  return SimpleCov::ResultMerger.merged_result
@@ -40,14 +59,6 @@ module SimpleCov
40
59
  self.running = false
41
60
  end
42
61
 
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
62
  #
52
63
  # Applies the configured filters to the given array of SimpleCov::SourceFile items
53
64
  #
@@ -1,9 +1,9 @@
1
1
  #
2
2
  # Adaptars are glorified SimpleCov configuration procs that can be easily
3
3
  # loaded using SimpleCov.start :rails and defined using
4
- # SimpleCov.adapters.define :foo do
5
- # # SimpleCov configuration here, same as in
6
- # end
4
+ # SimpleCov.adapters.define :foo do
5
+ # # SimpleCov configuration here, same as in SimpleCov.configure
6
+ # end
7
7
  #
8
8
  class SimpleCov::Adapters < Hash
9
9
  #
@@ -19,7 +19,7 @@ class SimpleCov::Adapters < Hash
19
19
  end
20
20
 
21
21
  #
22
- # Applies the adapter of given name
22
+ # Applies the adapter of given name on SimpleCov.configure
23
23
  #
24
24
  def load(name)
25
25
  name = name.to_sym
@@ -79,14 +79,15 @@ module SimpleCov::Configuration
79
79
  end
80
80
 
81
81
  #
82
- # Configure SimpleCov using a block:
82
+ # Allows you to configure simplecov in a block instead of prepending SimpleCov to all config methods
83
+ # you're calling.
83
84
  #
84
85
  # SimpleCov.configure do
85
86
  # add_filter 'foobar'
86
87
  # end
87
88
  #
88
- # This is equivalent to SimpleCov.add_filter 'foobar' and thus makes it easier to set a lot of configure
89
- # options.
89
+ # This is equivalent to SimpleCov.add_filter 'foobar' and thus makes it easier to set a buchn of configure
90
+ # options at once.
90
91
  #
91
92
  def configure(&block)
92
93
  instance_exec(&block)
@@ -109,6 +110,16 @@ module SimpleCov::Configuration
109
110
  @at_exit ||= Proc.new { SimpleCov.result.format! }
110
111
  end
111
112
 
113
+ #
114
+ # Returns the project name - currently assuming the last dirname in
115
+ # the SimpleCov.root is this.
116
+ #
117
+ def project_name(new_name=nil)
118
+ return @project_name if @project_name and new_name.nil?
119
+ @project_name = new_name if new_name.kind_of?(String)
120
+ @project_name ||= File.basename(root.split('/').last).capitalize.gsub('_', ' ')
121
+ end
122
+
112
123
  #
113
124
  # Defines whether to use result merging so all your test suites (test:units, test:functionals, cucumber, ...)
114
125
  # are joined and combined into a single coverage report
@@ -153,6 +164,11 @@ module SimpleCov::Configuration
153
164
  filters << parse_filter(filter_argument, &filter_proc)
154
165
  end
155
166
 
167
+ #
168
+ # Define a group for files. Works similar to add_filter, only that the first
169
+ # argument is the desired group name and files PASSING the filter end up in the group
170
+ # (while filters exclude when the filter is applicable).
171
+ #
156
172
  def add_group(group_name, filter_argument=nil, &filter_proc)
157
173
  groups[group_name] = parse_filter(filter_argument, &filter_proc)
158
174
  end
@@ -22,12 +22,16 @@ module SimpleCov
22
22
  end
23
23
 
24
24
  class StringFilter < SimpleCov::Filter
25
+ # Returns true when the given source file's filename matches the
26
+ # string configured when initializing this Filter with StringFilter.new('somestring)
25
27
  def passes?(source_file)
26
28
  !(source_file.filename =~ /#{filter_argument}/)
27
29
  end
28
30
  end
29
31
 
30
32
  class BlockFilter < SimpleCov::Filter
33
+ # Returns true if the block given when initializing this filter with BlockFilter.new {|src_file| ... }
34
+ # returns true for the given source file.
31
35
  def passes?(source_file)
32
36
  !filter_argument.call(source_file)
33
37
  end
@@ -1,6 +1,6 @@
1
1
  module SimpleCov
2
+ # TODO: Documentation on how to build your own formatters
2
3
  module Formatter
3
-
4
4
  end
5
5
  end
6
6
 
@@ -1,4 +1,8 @@
1
+ #
2
+ # A ridiculously simple formatter for SimpleCov results.
3
+ #
1
4
  class SimpleCov::Formatter::SimpleFormatter
5
+ # Takes a SimpleCov::Result and generates a string out of it
2
6
  def format(result)
3
7
  output = ""
4
8
  result.groups.each do |name, files|
@@ -1,4 +1,5 @@
1
1
  module SimpleCov::ArrayMergeHelper
2
+ # Merges an array of coverage results with self
2
3
  def merge_resultset(array)
3
4
  new_array = []
4
5
 
@@ -20,6 +21,7 @@ module SimpleCov::ArrayMergeHelper
20
21
  end
21
22
 
22
23
  module SimpleCov::HashMergeHelper
24
+ # Merges the given Coverage.result hash with self
23
25
  def merge_resultset(hash)
24
26
  new_resultset = {}
25
27
  (self.keys + hash.keys).each do |filename|
@@ -2,45 +2,63 @@ require 'digest/sha1'
2
2
  require 'yaml'
3
3
 
4
4
  module SimpleCov
5
+ #
6
+ # A simplecov code coverage result, initialized from the Hash Ruby 1.9's built-in coverage
7
+ # library generates (Coverage.result).
8
+ #
5
9
  class Result
6
- attr_reader :original_result, :files
7
- attr_writer :created_at, :command_name
10
+ # Returns the original Coverage.result used for this instance of SimpleCov::Result
11
+ attr_reader :original_result
12
+ # Returns all files that are applicable to this result (sans filters!) as instances of SimpleCov::SourceFile. Aliased as :source_files
13
+ attr_reader :files
8
14
  alias_method :source_files, :files
15
+ # Explicitly set the Time this result has been created
16
+ attr_writer :created_at
17
+ # Explicitly set the command name that was used for this coverage result. Defaults to SimpleCov.command_name
18
+ attr_writer :command_name
9
19
 
20
+ # Initialize a new SimpleCov::Result from given Coverage.result (a Hash of filenames each containing an array of
21
+ # coverage data)
10
22
  def initialize(original_result)
11
23
  @original_result = original_result.freeze
12
24
  @files = original_result.map {|filename, coverage| SimpleCov::SourceFile.new(filename, coverage)}.sort_by(&:filename)
13
25
  filter!
14
26
  end
15
27
 
28
+ # Returns all filenames for source files contained in this result
16
29
  def filenames
17
30
  files.map(&:filename)
18
31
  end
19
32
 
33
+ # Returns a Hash of groups for this result. Define groups using SimpleCov.add_group 'Models', 'app/models'
20
34
  def groups
21
35
  @groups ||= SimpleCov.grouped(files)
22
36
  end
23
37
 
38
+ # The overall percentual coverage for this result
39
+ #
40
+ # FIXME: Kind of inaccurate - should use LOC instead of Files count!
24
41
  def covered_percent
25
42
  files.map(&:covered_percent).inject(:+) / files.count.to_f
26
43
  end
27
44
 
45
+ # Applies the configured SimpleCov.formatter on this result
28
46
  def format!
29
47
  SimpleCov.formatter.new.format(self)
30
48
  end
31
49
 
32
- # Defines when this result has been created
50
+ # Defines when this result has been created. Defaults to Time.now
33
51
  def created_at
34
52
  @created_at ||= Time.now
35
53
  end
36
54
 
37
- # The command name that launched this result.
55
+ # The command name that launched this result.
38
56
  # Retrieved from SimpleCov.command_name
39
57
  def command_name
40
58
  @command_name ||= SimpleCov.command_name
41
59
  end
42
60
 
43
- # Returns a hash representation of this Result
61
+ # Returns a hash representation of this Result that can be used for marshalling it into YAML
44
62
  def to_hash
45
63
  {command_name => {:original_result => original_result.reject {|filename, result| !filenames.include?(filename) }, :created_at => created_at}}
46
64
  end
@@ -66,6 +84,7 @@ module SimpleCov
66
84
 
67
85
  private
68
86
 
87
+ # Applies all configured SimpleCov filters on this result's source files
69
88
  def filter!
70
89
  @files = SimpleCov.filtered(files)
71
90
  end
@@ -1,15 +1,26 @@
1
1
  require 'yaml'
2
+ #
3
+ # Singleton that is responsible for caching, loading and merging
4
+ # SimpleCov::Results into a single result for coverage analysis based
5
+ # upon multiple test suites.
6
+ #
2
7
  module SimpleCov::ResultMerger
3
8
  class << self
9
+ # The path to the resultset.yml cache file
4
10
  def resultset_path
5
11
  File.join(SimpleCov.coverage_path, 'resultset.yml')
6
12
  end
7
13
 
14
+ # Loads the cached resultset from YAML and returns it as a Hash
8
15
  def resultset
9
16
  return {} unless File.exist?(resultset_path)
10
17
  YAML.load(File.read(resultset_path))
11
18
  end
12
19
 
20
+ # Gets the resultset hash and re-creates all included instances
21
+ # of SimpleCov::Result from that.
22
+ # All results that are above the SimpleCov.merge_timeout will be
23
+ # dropped. Returns an array of SimpleCov::Result items.
13
24
  def results
14
25
  results = []
15
26
  resultset.each do |command_name, data|
@@ -22,6 +33,11 @@ module SimpleCov::ResultMerger
22
33
  results
23
34
  end
24
35
 
36
+ #
37
+ # Gets all SimpleCov::Results from cache, merges them and produces a new
38
+ # SimpleCov::Result with merged coverage data and the command_name
39
+ # for the result consisting of a join on all source result's names
40
+ #
25
41
  def merged_result
26
42
  merged = {}
27
43
  results.each do |result|
@@ -33,6 +49,7 @@ module SimpleCov::ResultMerger
33
49
  result
34
50
  end
35
51
 
52
+ # Saves the given SimpleCov::Result in the resultset cache
36
53
  def store_result(result)
37
54
  new_set = resultset
38
55
  command_name, data = result.to_hash.first
@@ -1,4 +1,8 @@
1
1
  module SimpleCov
2
+ #
3
+ # Representation of a source file including it's coverage data, source code,
4
+ # source lines and featuring helpers to interpret that data.
5
+ #
2
6
  class SourceFile
3
7
  # Representation of a single line in a source file including
4
8
  # this specific line's source code, line_number and code coverage,
@@ -6,7 +10,12 @@ module SimpleCov
6
10
  # line), 0 (line not covered) or >1 (the amount of times the line was
7
11
  # executed)
8
12
  class Line
9
- attr_reader :src, :line_number, :coverage
13
+ # The source code for this line. Aliased as :source
14
+ attr_reader :src
15
+ # The line number in the source file. Aliased as :line, :number
16
+ attr_reader :line_number
17
+ # The coverage data for this line: either nil (never), 0 (missed) or >=1 (times covered)
18
+ attr_reader :coverage
10
19
  # Lets grab some fancy aliases, shall we?
11
20
  alias_method :source, :src
12
21
  alias_method :line, :line_number
@@ -19,48 +28,71 @@ module SimpleCov
19
28
  @src, @line_number, @coverage = src, line_number, coverage
20
29
  end
21
30
 
31
+ # Returns true if this is a line that should have been covered, but was not
22
32
  def missed?
23
33
  not never? and coverage == 0
24
34
  end
25
35
 
36
+ # Returns true if this is a line that has been covered
26
37
  def covered?
27
38
  not never? and coverage > 0
28
39
  end
29
40
 
41
+ # Returns true if this line is not relevant for coverage
30
42
  def never?
31
43
  coverage.nil?
32
44
  end
33
45
  end
34
46
 
35
- attr_reader :filename, :coverage, :src, :lines
47
+ # The full path to this source file (e.g. /User/colszowka/projects/simplecov/lib/simplecov/source_file.rb)
48
+ attr_reader :filename
49
+ # The array of coverage data received from the Coverage.result
50
+ attr_reader :coverage
51
+ # The source code for this file. Aliased as :source
52
+ attr_reader :src
36
53
  alias_method :source, :src
37
- alias_method :source_lines, :lines
38
54
 
39
55
  def initialize(filename, coverage)
40
56
  @filename, @coverage, @src = filename, coverage, File.readlines(filename)
57
+ end
58
+
59
+ # Returns all source lines for this file as instances of SimpleCov::SourceFile::Line,
60
+ # and thus including coverage data. Aliased as :source_lines
61
+ def lines
62
+ return @lines unless @lines.nil?
63
+ # Initialize lines
41
64
  @lines = []
42
65
  coverage.each_with_index do |coverage, i|
43
66
  @lines << SimpleCov::SourceFile::Line.new(src[i], i+1, coverage)
44
67
  end
68
+ @lines
45
69
  end
70
+ alias_method :source_lines, :lines
46
71
 
72
+ # Access SimpleCov::SourceFile::Line source lines by line number
47
73
  def line(number)
48
74
  lines[number-1]
49
75
  end
50
76
 
77
+ # The coverage for this file in percent. 0 if the file has no relevant lines
51
78
  def covered_percent
52
79
  return 100.0 if lines.length == 0 or lines.length == never_lines.count
53
80
  (covered_lines.count) * 100 / (lines.count-never_lines.count).to_f
54
81
  end
55
82
 
83
+ # Returns all covered lines as SimpleCov::SourceFile::Line
56
84
  def covered_lines
57
85
  @covered_lines ||= lines.select {|c| c.covered? }
58
86
  end
59
87
 
88
+ # Returns all lines that should have been, but were not covered
89
+ # as instances of SimpleCov::SourceFile::Line
60
90
  def missed_lines
61
91
  @missed_lines ||= lines.select {|c| c.missed? }
62
92
  end
63
93
 
94
+ # Returns all lines that are not relevant for coverage as
95
+ # SimpleCov::SourceFile::Line instances
64
96
  def never_lines
65
97
  @never_lines ||= lines.select {|c| c.never? }
66
98
  end
data/simplecov.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{simplecov}
8
- s.version = "0.3.0"
8
+ s.version = "0.3.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Christoph Olszowka"]
12
- s.date = %q{2010-08-22}
12
+ s.date = %q{2010-08-23}
13
13
  s.description = %q{Code coverage for Ruby 1.9}
14
14
  s.email = %q{christoph at olszowka.de}
15
15
  s.extra_rdoc_files = [
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 0
9
- version: 0.3.0
8
+ - 1
9
+ version: 0.3.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Christoph Olszowka
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-08-22 00:00:00 +02:00
17
+ date: 2010-08-23 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency