solargraph_test_coverage 0.2.0 → 0.2.4
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -2
- data/lib/solargraph_test_coverage/config.rb +2 -1
- data/lib/solargraph_test_coverage/helpers.rb +25 -53
- data/lib/solargraph_test_coverage/test_coverage_reporter.rb +30 -27
- data/lib/solargraph_test_coverage/test_runner.rb +13 -1
- data/lib/solargraph_test_coverage/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: afacac1a6d557ea7ef39c86081fc7f3aafcb7e09c3a8243679e9d252ba47a2c7
|
4
|
+
data.tar.gz: 9e929da5ff5873ef3c044edebb4a96575cb47f4bfb9b2d36121082257ac03569
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58b77e64736847a4d5d6fedb3c67f7b76e6af6056e844926356269c052b8bfe5f29af0c1f76e916f2e26d1ddb5c5628d3d324f53c890ceeff55f289959409b8c
|
7
|
+
data.tar.gz: 92e5f351f941d99103339f80fb05450e1393cb5929f584cd7d080759450f9cd31422a71d51ba847664b1217b88c761f1f132f346f280106580c8c806ba1c6bd9
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -9,8 +9,6 @@ Currently there are four different diagnostics:
|
|
9
9
|
- Spec cannot be found (Error message will be on line 1)
|
10
10
|
|
11
11
|
|
12
|
-
Currently expects RSpec/Rails.
|
13
|
-
|
14
12
|
## Installation
|
15
13
|
|
16
14
|
Add this line to your application's Gemfile:
|
@@ -41,6 +39,7 @@ test_coverage:
|
|
41
39
|
- test_missing
|
42
40
|
exclude_paths:
|
43
41
|
- 'app/controller'
|
42
|
+
- 'concerns'
|
44
43
|
```
|
45
44
|
|
46
45
|
|
@@ -1,51 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module SolargraphTestCoverage
|
4
|
+
# Some helper functions for the diagnostics
|
4
5
|
module Helpers
|
5
|
-
#
|
6
|
-
# Determines if a file should be excluded from running diagnostics
|
7
|
-
#
|
8
6
|
# @return [Boolean]
|
9
|
-
#
|
10
7
|
def exclude_file?(source_filename)
|
11
|
-
return true if source_filename.start_with?
|
8
|
+
return true if source_filename.start_with? Helpers.test_path
|
12
9
|
|
13
10
|
Config.exclude_paths.each { |path| return true if source_filename.sub(Dir.pwd, '').include? path }
|
14
11
|
|
15
12
|
false
|
16
13
|
end
|
17
14
|
|
18
|
-
#
|
19
|
-
# Attempts to find the corresponding unit test file
|
20
|
-
#
|
21
15
|
# @return [String]
|
22
|
-
#
|
23
16
|
def test_file(source)
|
24
|
-
|
25
|
-
|
26
|
-
relative_filepath[0] = Config.test_dir
|
27
|
-
|
28
|
-
File.join(Dir.pwd, relative_filepath.join('/'))
|
29
|
-
.sub('.rb', Config.test_file_suffix)
|
30
|
-
end
|
31
|
-
end
|
17
|
+
relative_filepath = source.location.filename.sub(Dir.pwd, '').split('/').reject(&:empty?)
|
18
|
+
relative_filepath[0] = Config.test_dir
|
32
19
|
|
33
|
-
|
34
|
-
|
35
|
-
#
|
36
|
-
# @return [Hash]
|
37
|
-
#
|
38
|
-
def results(source)
|
39
|
-
@results ||= run_test(source)
|
20
|
+
File.join(Dir.pwd, relative_filepath.join('/'))
|
21
|
+
.sub('.rb', Config.test_file_suffix)
|
40
22
|
end
|
41
23
|
|
42
|
-
#
|
43
|
-
# Runs RSpec on test file in a child process
|
44
|
-
# Returns coverage results for current working file
|
45
|
-
# RSpec::Core::Runner.run will return 0 if the test file passes, and 1 if it does not.
|
46
|
-
#
|
47
24
|
# @return [Hash]
|
48
|
-
#
|
49
25
|
def run_test(source)
|
50
26
|
ForkProcess.run do
|
51
27
|
Coverage.start(lines: true, branches: true)
|
@@ -54,7 +30,6 @@ module SolargraphTestCoverage
|
|
54
30
|
end
|
55
31
|
end
|
56
32
|
|
57
|
-
#
|
58
33
|
# Adapted from SingleCov
|
59
34
|
# Coverage returns nil for untestable lines (like do, end, if keywords)
|
60
35
|
# otherwise returns int showing how many times a line was called
|
@@ -64,28 +39,24 @@ module SolargraphTestCoverage
|
|
64
39
|
# @return [Array]
|
65
40
|
#
|
66
41
|
def uncovered_lines(results)
|
67
|
-
results
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
42
|
+
return [] unless results[:lines]
|
43
|
+
|
44
|
+
results[:lines].each_with_index
|
45
|
+
.select { |c, _| c&.zero? }
|
46
|
+
.map { |_, i| i }
|
47
|
+
.compact
|
72
48
|
end
|
73
49
|
|
74
|
-
#
|
75
|
-
# Builds a new Branch object for each branch tested from results hash
|
76
|
-
# Then removes branches which have test coverage
|
77
|
-
#
|
78
50
|
# @return [Array]
|
79
|
-
#
|
80
51
|
def uncovered_branches(results)
|
81
52
|
Branch.build_from(results).reject(&:covered?)
|
82
53
|
end
|
83
54
|
|
84
|
-
#
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
55
|
+
# @return [Hash]
|
56
|
+
def range(start_line, start_column, end_line, end_column)
|
57
|
+
Solargraph::Range.from_to(start_line, start_column, end_line, end_column).to_hash
|
58
|
+
end
|
59
|
+
|
89
60
|
def self.require_testing_framework!
|
90
61
|
case Config.test_framework
|
91
62
|
when 'rspec'
|
@@ -97,7 +68,6 @@ module SolargraphTestCoverage
|
|
97
68
|
end
|
98
69
|
end
|
99
70
|
|
100
|
-
#
|
101
71
|
# Only called once, when gem is loaded
|
102
72
|
# Preloads rails via spec/rails_helper if Rails isn't already defined
|
103
73
|
# This gives us a nice speed-boost when running test in child process
|
@@ -112,18 +82,15 @@ module SolargraphTestCoverage
|
|
112
82
|
# calling Coverage.result after requiring stops and resets it.
|
113
83
|
#
|
114
84
|
# This is a bit experimental - I'm not sure if there will be downstream side-effects
|
115
|
-
# from having Rails preloaded, but... we'll see :)
|
116
85
|
#
|
117
86
|
# @return [Boolean]
|
118
87
|
#
|
119
88
|
def self.preload_rails!
|
120
|
-
return if defined?(Rails)
|
121
|
-
return unless File.file?('spec/rails_helper.rb')
|
89
|
+
return if defined?(Rails) || !File.file?('spec/rails_helper.rb')
|
122
90
|
|
123
|
-
|
124
|
-
$LOAD_PATH.unshift(spec_path) unless $LOAD_PATH.include?(spec_path)
|
91
|
+
$LOAD_PATH.unshift(test_path) unless $LOAD_PATH.include?(test_path)
|
125
92
|
|
126
|
-
require File.
|
93
|
+
require File.join(test_path, 'rails_helper')
|
127
94
|
Coverage.result(stop: true, clear: true) if Coverage.running?
|
128
95
|
|
129
96
|
true
|
@@ -133,5 +100,10 @@ module SolargraphTestCoverage
|
|
133
100
|
|
134
101
|
false
|
135
102
|
end
|
103
|
+
|
104
|
+
# @return [String]
|
105
|
+
def self.test_path
|
106
|
+
File.join(Dir.pwd, Config.test_dir)
|
107
|
+
end
|
136
108
|
end
|
137
109
|
end
|
@@ -5,65 +5,71 @@ module SolargraphTestCoverage
|
|
5
5
|
class TestCoverageReporter < Solargraph::Diagnostics::Base
|
6
6
|
include Helpers
|
7
7
|
|
8
|
-
#
|
9
8
|
# LSP Diagnostic method
|
10
|
-
#
|
11
9
|
# @return [Array]
|
12
10
|
#
|
13
11
|
def diagnose(source, _api_map)
|
14
12
|
return [] if source.code.empty? || exclude_file?(source.location.filename)
|
15
13
|
return [test_missing_error(source)] unless File.file?(test_file(source))
|
16
14
|
|
17
|
-
|
15
|
+
results = run_test(source)
|
16
|
+
messages(source, results)
|
18
17
|
rescue ChildFailedError
|
19
18
|
[]
|
20
19
|
end
|
21
20
|
|
22
21
|
private
|
23
22
|
|
24
|
-
|
23
|
+
# Compiles all diagnostic messages for source file
|
24
|
+
# @return [Array]
|
25
|
+
#
|
26
|
+
def messages(source, results)
|
25
27
|
messages = [
|
26
|
-
line_warnings(source),
|
27
|
-
branch_warnings(source),
|
28
|
-
test_passing_error(source)
|
28
|
+
line_warnings(source, results),
|
29
|
+
branch_warnings(source, results),
|
30
|
+
test_passing_error(source, results)
|
29
31
|
]
|
30
32
|
|
31
33
|
messages.flatten.compact
|
32
34
|
end
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
+
# Creates array of warnings for uncovered lines
|
37
|
+
# @return [Array]
|
38
|
+
#
|
39
|
+
def line_warnings(source, results)
|
40
|
+
uncovered_lines(results).map { |line| line_coverage_warning(source, line) }
|
36
41
|
end
|
37
42
|
|
38
|
-
|
39
|
-
|
43
|
+
# Creates array of warnings for uncovered branches
|
44
|
+
# @return [Array]
|
45
|
+
#
|
46
|
+
def branch_warnings(source, results)
|
47
|
+
uncovered_branches(results).map { |branch| branch_coverage_warning(source, branch.report) }
|
40
48
|
end
|
41
49
|
|
42
|
-
|
43
|
-
|
50
|
+
# Creates array containing error for failing spec
|
51
|
+
# @return [Array]
|
52
|
+
#
|
53
|
+
def test_passing_error(source, results)
|
54
|
+
results[:test_status] ? [] : [test_failing_error(source)]
|
44
55
|
end
|
45
56
|
|
46
|
-
#
|
47
57
|
# Creates LSP warning message for missing line coverage
|
48
|
-
#
|
49
58
|
# @return [Hash]
|
50
59
|
#
|
51
60
|
def line_coverage_warning(source, line)
|
52
61
|
return unless Config.line_coverage?
|
53
62
|
|
54
63
|
{
|
55
|
-
range:
|
64
|
+
range: range(line, 0, line, source.code.lines[line].length),
|
56
65
|
severity: Solargraph::Diagnostics::Severities::WARNING,
|
57
66
|
source: 'TestCoverage',
|
58
67
|
message: 'Line is missing test coverage'
|
59
68
|
}
|
60
69
|
end
|
61
70
|
|
62
|
-
#
|
63
71
|
# Creates LSP warning message for missing branch coverage
|
64
|
-
#
|
65
|
-
# starts counting lines at 1, while the LSP (source.code.line) is an array
|
66
|
-
# with an index starting at 0
|
72
|
+
# Line numbers are off by 1, since Branch Coverage starts counting at 1, not 0
|
67
73
|
#
|
68
74
|
# @return [Hash]
|
69
75
|
#
|
@@ -71,24 +77,21 @@ module SolargraphTestCoverage
|
|
71
77
|
return unless Config.branch_coverage?
|
72
78
|
|
73
79
|
{
|
74
|
-
range:
|
75
|
-
source.code.lines[report[:line] - 1].length).to_hash,
|
80
|
+
range: range(report[:line] - 1, 0, report[:line] - 1, source.code.lines[report[:line] - 1].length),
|
76
81
|
severity: Solargraph::Diagnostics::Severities::WARNING,
|
77
82
|
source: 'TestCoverage',
|
78
83
|
message: "'#{report[:type].upcase}' branch is missing test coverage"
|
79
84
|
}
|
80
85
|
end
|
81
86
|
|
82
|
-
#
|
83
|
-
# Creates LSP error message if test is failing
|
84
|
-
#
|
87
|
+
# Creates LSP error message if test file is failing
|
85
88
|
# @return [Hash]
|
86
89
|
#
|
87
90
|
def test_failing_error(source)
|
88
91
|
return unless Config.test_failing_coverage?
|
89
92
|
|
90
93
|
{
|
91
|
-
range:
|
94
|
+
range: range(0, 0, 0, source.code.lines[0].length),
|
92
95
|
severity: Solargraph::Diagnostics::Severities::ERROR,
|
93
96
|
source: 'TestCoverage',
|
94
97
|
message: 'Unit Test is currently failing.'
|
@@ -104,7 +107,7 @@ module SolargraphTestCoverage
|
|
104
107
|
return unless Config.test_missing_coverage?
|
105
108
|
|
106
109
|
{
|
107
|
-
range:
|
110
|
+
range: range(0, 0, 0, source.code.lines[0].length),
|
108
111
|
severity: Solargraph::Diagnostics::Severities::ERROR,
|
109
112
|
source: 'TestCoverage',
|
110
113
|
message: "No unit test file found at #{test_file(source)}"
|
@@ -18,10 +18,14 @@ module SolargraphTestCoverage
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def run!
|
21
|
-
@result = test_framework_runner.run(
|
21
|
+
@result = test_framework_runner.run(test_options)
|
22
22
|
self
|
23
23
|
end
|
24
24
|
|
25
|
+
def test_options
|
26
|
+
raise NotImplementedError
|
27
|
+
end
|
28
|
+
|
25
29
|
def passed?
|
26
30
|
raise NotImplementedError
|
27
31
|
end
|
@@ -33,6 +37,10 @@ module SolargraphTestCoverage
|
|
33
37
|
|
34
38
|
# Test Runner Subclass for RSpec
|
35
39
|
class RSpecRunner < TestRunner
|
40
|
+
def test_options
|
41
|
+
[@test_file, '-o', '/dev/null']
|
42
|
+
end
|
43
|
+
|
36
44
|
def passed?
|
37
45
|
@result&.zero?
|
38
46
|
end
|
@@ -44,6 +52,10 @@ module SolargraphTestCoverage
|
|
44
52
|
|
45
53
|
# Test Runner Subclass for Minitest
|
46
54
|
class MinitestRunner < TestRunner
|
55
|
+
def test_options
|
56
|
+
[@test_file]
|
57
|
+
end
|
58
|
+
|
47
59
|
def passed?
|
48
60
|
@result
|
49
61
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solargraph_test_coverage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cameron Kolkey
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-09-
|
11
|
+
date: 2021-09-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: solargraph
|