covered 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e4e02c3c03842ced3f0f2b325fbdc6cd6a56b1ca88341bf53108f760f319b9ea
4
- data.tar.gz: 21cb38f3723b640c0b059f5672509830c4e864456bac07fc1d16bb81ad636cd7
3
+ metadata.gz: 427269046d977cdbbf273f6b037306b94b767bac227611c4bb088284ba386a3d
4
+ data.tar.gz: 60562f99f72cb13819d75f53ee9d4d24397d3391656e005def4b085ef48b607f
5
5
  SHA512:
6
- metadata.gz: a2f58e90824ad8b42075984a06f187d96b2e166affc7a8882383612cca9627c79fdafd2d0bdc55459347bfee5bc46d5ab10749271b2e7667cefa47381190f12e
7
- data.tar.gz: 319a678ee8bd7a6660a7d6f9908b80810e4a67b19e3f79ae3a17d35e45e0c00c619c5cf0bbd1e726789e2319a6ed9c7d54d26e4f78a20282ae5208e48d29ff8d
6
+ metadata.gz: 5957818e2d53357da2fd7874d1040a36dd032d1ba287047724684f1702b2d866a66910c3b1254b4ee2788751e0016de6eb26fa17392c6758e524f9a69e3c5125
7
+ data.tar.gz: 749be10e7c7a56a8f93b34c347abab188aafde3ee0af70806e2d4e991a7a9c4ed6dd5a1eb05ea1ce46907fe4e5463460a48b3e1006b7a67f4cb40a03781a1a8b
data/.editorconfig ADDED
@@ -0,0 +1,6 @@
1
+ root = true
2
+
3
+ [*]
4
+ indent_style = tab
5
+ indent_size = 2
6
+
data/README.md CHANGED
@@ -1,36 +1,66 @@
1
1
  # Covered [![Build Status](https://travis-ci.com/ioquatix/covered.svg)](https://travis-ci.com/ioquatix/covered)
2
2
 
3
- Covered uses modern Ruby features to generate comprehensive coverage, including support for templates which are compiled into Ruby. **This only works with Ruby 2.6 and its experimental support for RubyVM::AbstractSyntaxTree**
3
+ Covered uses modern Ruby features to generate comprehensive coverage, including support for templates which are compiled into Ruby.
4
4
 
5
5
  ![Screenshot](media/example.png)
6
6
 
7
7
  ## Motivation
8
8
 
9
- Existing Ruby coverage tools are unable to handle `eval`ed code. This is because the `coverage` module built into Ruby doesn't expose the necessary hooks to capture it. With Ruby 2.6, `RubyVM::AST.parse(source)` came into existence, which gives us a fine grained tool for computing initial source coverage (i.e. what lines are executable), and thus making it possible to compute coverage for "templates".
9
+ Existing Ruby coverage tools are unable to handle `eval`ed code. This is because the `coverage` module built into Ruby doesn't expose the necessary hooks to capture it. Using the [parser] gem allows us to do our own source code analysis to compute executable lines, thus making it possible to compute coverage for "templates".
10
10
 
11
11
  It's still tricky to do it correctly, but it is feasible now to compute coverage of web application "views" by using this technique. This gem is an exploration to see what is possible.
12
12
 
13
+ [parser]: https://github.com/whitequark/parser
14
+
13
15
  ## Installation
14
16
 
15
- Add this line to your application's Gemfile:
17
+ Add this line to your application's `Gemfile`:
16
18
 
17
- gem 'covered'
19
+ ```ruby
20
+ group :test do
21
+ gem 'covered', require: 'covered/rspec'
22
+ end
23
+ ```
18
24
 
19
- And then execute:
25
+ In your `spec/spec_helper.rb` add the following before loading any other code:
20
26
 
21
- $ bundle
27
+ ```ruby
28
+ require 'bundler/setup'
29
+ Bundler.require(:test)
30
+ ```
22
31
 
23
- Or install it yourself as:
32
+ Ensure that you have a `.rspec` file with `--require spec_helper`:
24
33
 
25
- $ gem install covered
34
+ ```
35
+ --require spec_helper
36
+ --format documentation
37
+ --warnings
38
+ ```
26
39
 
27
40
  ## Usage
28
41
 
29
- For `rspec`, simply include the following from your `spec_helper.rb`
42
+ When running `rspec`, you can specify the kind of coverage analysis you would like:
43
+
44
+ ```
45
+ COVERAGE=Summary rspec
46
+ ```
47
+
48
+ ### Partial Summary
49
+
50
+ ```
51
+ COVERAGE=PartialSummary rspec
52
+ ```
53
+
54
+ This report only shows snippets of source code with incomplete coverage.
55
+
56
+ ### Brief Summary
57
+
30
58
 
31
- ```ruby
32
- require 'covered/rspec'
33
59
  ```
60
+ COVERAGE=BriefSummary rspec
61
+ ```
62
+
63
+ This report lists several files in order of least coverage.
34
64
 
35
65
  ## Contributing
36
66
 
data/covered.gemspec CHANGED
@@ -17,11 +17,11 @@ Gem::Specification.new do |spec|
17
17
 
18
18
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
19
  spec.require_paths = ["lib"]
20
-
21
- spec.required_ruby_version = '~> 2.6.0'
22
-
20
+
23
21
  spec.add_dependency "rainbow"
24
22
 
23
+ spec.add_dependency "parser"
24
+
25
25
  spec.add_development_dependency "trenni", "~> 3.6"
26
26
 
27
27
  spec.add_development_dependency "bundler"
@@ -74,8 +74,12 @@ module Covered
74
74
  @output = Root.new(@output, *args)
75
75
  end
76
76
 
77
+ def cache!
78
+ @output = Cache.new(@output)
79
+ end
80
+
77
81
  def capture
78
- @capture ||= Capture.new(Cache.new(@output))
82
+ @capture ||= Capture.new(@output)
79
83
  end
80
84
 
81
85
  def enable
@@ -0,0 +1,38 @@
1
+ # Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ $covered = Covered.policy do
22
+ cache!
23
+
24
+ # Only files in the root would be tracked:
25
+ root Dir.pwd
26
+
27
+ # We will ignore any files in the spec directory:
28
+ skip /spec/
29
+
30
+ # We will include all files under lib, even if they aren't loaded:
31
+ include "lib/**/*.rb"
32
+
33
+ source
34
+
35
+ if coverage = ENV['COVERAGE']
36
+ self.summary_class = Covered.const_get(coverage) || Covered::BriefSummary
37
+ end
38
+ end
data/lib/covered/rspec.rb CHANGED
@@ -18,27 +18,10 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  # THE SOFTWARE.
20
20
 
21
- require_relative '../covered'
22
- require 'rspec/core/formatters'
21
+ require_relative 'policy'
22
+ require_relative 'policy/default'
23
23
 
24
- $covered = Covered.policy do
25
- # Only files in the root would be tracked:
26
- root Dir.pwd
27
-
28
- # We will ignore any files in the spec directory:
29
- skip /spec/
30
-
31
- # We will include all files under lib, even if they aren't loaded:
32
- include "lib/**/*.rb"
33
-
34
- source
35
-
36
- if coverage = ENV['COVERAGE']
37
- self.summary_class = Covered.const_get(coverage)
38
- else
39
- self.summary_class = Covered::BriefSummary
40
- end
41
- end
24
+ require 'rspec/core/formatters'
42
25
 
43
26
  module Covered
44
27
  module RSpec
@@ -72,12 +55,14 @@ module Covered
72
55
  end
73
56
  end
74
57
 
75
- RSpec::Core::Configuration.prepend(Covered::RSpec::Policy)
58
+ if ENV['COVERAGE']
59
+ RSpec::Core::Configuration.prepend(Covered::RSpec::Policy)
76
60
 
77
- RSpec.configure do |config|
78
- config.add_formatter(Covered::RSpec::Formatter)
79
-
80
- config.after(:suite) do
81
- $covered.disable
61
+ RSpec.configure do |config|
62
+ config.add_formatter(Covered::RSpec::Formatter)
63
+
64
+ config.after(:suite) do
65
+ $covered.disable
66
+ end
82
67
  end
83
68
  end
@@ -23,6 +23,8 @@ require_relative 'wrapper'
23
23
 
24
24
  require 'thread'
25
25
 
26
+ require 'parser/current'
27
+
26
28
  module Covered
27
29
  # The source map, loads the source file, parses the AST to generate which lines contain executable code.
28
30
  class Source < Wrapper
@@ -70,22 +72,21 @@ module Covered
70
72
  end
71
73
 
72
74
  def executable?(node)
73
- node.type.to_s =~ @executable
75
+ node.type == :send
74
76
  end
75
77
 
76
78
  def ignore?(node)
77
- # NODE_ARGS Ruby doesn't report execution of arguments in :line tracepoint.
78
- node.nil? or node.type.to_s =~ @ignore
79
+ node.nil? or node.type == :arg
79
80
  end
80
81
 
81
82
  def expand(node, coverage, level = 0)
82
- if node.is_a? RubyVM::AbstractSyntaxTree::Node
83
+ if node.is_a? Parser::AST::Node
83
84
  if ignore?(node)
84
- coverage.annotate(node.first_lineno, "ignoring #{node.type}")
85
+ coverage.annotate(node.location.line, "ignoring #{node.type}")
85
86
  else
86
87
  if executable?(node)
87
88
  # coverage.annotate(node.first_lineno, "executable #{node.type}")
88
- coverage.counts[node.first_lineno] ||= 0
89
+ coverage.counts[node.location.line] ||= 0
89
90
  else
90
91
  # coverage.annotate(node.first_lineno, "not executable #{node.type}")
91
92
  end
@@ -103,9 +104,9 @@ module Covered
103
104
 
104
105
  def parse(path)
105
106
  if source = @paths[path]
106
- RubyVM::AbstractSyntaxTree.parse(source)
107
+ Parser::CurrentRuby.parse(source)
107
108
  elsif File.exist?(path)
108
- RubyVM::AbstractSyntaxTree.parse_file(path)
109
+ Parser::CurrentRuby.parse_file(path)
109
110
  else
110
111
  warn "Couldn't parse #{path}, file doesn't exist?"
111
112
  end
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Covered
22
- VERSION = "0.7.0"
22
+ VERSION = "0.8.0"
23
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: covered
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-27 00:00:00.000000000 Z
11
+ date: 2019-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rainbow
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: parser
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: trenni
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -87,6 +101,7 @@ executables: []
87
101
  extensions: []
88
102
  extra_rdoc_files: []
89
103
  files:
104
+ - ".editorconfig"
90
105
  - ".gitignore"
91
106
  - ".rspec"
92
107
  - ".travis.yml"
@@ -100,6 +115,7 @@ files:
100
115
  - lib/covered/eval.rb
101
116
  - lib/covered/files.rb
102
117
  - lib/covered/policy.rb
118
+ - lib/covered/policy/default.rb
103
119
  - lib/covered/rspec.rb
104
120
  - lib/covered/source.rb
105
121
  - lib/covered/statistics.rb
@@ -116,16 +132,16 @@ require_paths:
116
132
  - lib
117
133
  required_ruby_version: !ruby/object:Gem::Requirement
118
134
  requirements:
119
- - - "~>"
135
+ - - ">="
120
136
  - !ruby/object:Gem::Version
121
- version: 2.6.0
137
+ version: '0'
122
138
  required_rubygems_version: !ruby/object:Gem::Requirement
123
139
  requirements:
124
140
  - - ">="
125
141
  - !ruby/object:Gem::Version
126
142
  version: '0'
127
143
  requirements: []
128
- rubygems_version: 3.0.1
144
+ rubygems_version: 3.0.2
129
145
  signing_key:
130
146
  specification_version: 4
131
147
  summary: A modern approach to code coverage.