solargraph_test_coverage 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 17b226826380f6ebff660ad770a654eba615c2dcb6070f15ec1ba65c31b2d68b
4
+ data.tar.gz: cfc0da7a98ffbcebaa9e567d513fe60e64f6a084cc8cb00f254c5ab242f33e20
5
+ SHA512:
6
+ metadata.gz: 4f67f75212d3291c8c5201633d5847f28b30a731f4e90cf4a341a4a83701cc9a6c9c4c58a8530769d9d1bb41123c0e8fc4df9c7f4f006d50a60b0f16068dd39f
7
+ data.tar.gz: 47a3455b307c0144c0ff5f2ff440aef688002978ab6db7fa48804a49db833721d9d9a6b03ae362aaf67b537b137676380642eea70eaea94e32c2d9b66bedbbe2
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.6.3
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in solargraph_test_coverage.gemspec
4
+ gemspec
5
+
6
+ gem "rake", "~> 12.0"
data/Gemfile.lock ADDED
@@ -0,0 +1,76 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ solargraph_test_coverage (0.1.1)
5
+ rspec-core (~> 3.10, >= 3.10.0)
6
+ solargraph (~> 0.40, > 0.40)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ ast (2.4.2)
12
+ backport (1.2.0)
13
+ benchmark (0.1.1)
14
+ diff-lcs (1.4.4)
15
+ e2mmap (0.1.0)
16
+ jaro_winkler (1.5.4)
17
+ kramdown (2.3.1)
18
+ rexml
19
+ kramdown-parser-gfm (1.1.0)
20
+ kramdown (~> 2.0)
21
+ nokogiri (1.12.3-x86_64-darwin)
22
+ racc (~> 1.4)
23
+ parallel (1.20.1)
24
+ parser (3.0.2.0)
25
+ ast (~> 2.4.1)
26
+ racc (1.5.2)
27
+ rainbow (3.0.0)
28
+ rake (12.3.2)
29
+ regexp_parser (2.1.1)
30
+ reverse_markdown (2.0.0)
31
+ nokogiri
32
+ rexml (3.2.5)
33
+ rspec-core (3.10.1)
34
+ rspec-support (~> 3.10.0)
35
+ rspec-support (3.10.2)
36
+ rubocop (1.20.0)
37
+ parallel (~> 1.10)
38
+ parser (>= 3.0.0.0)
39
+ rainbow (>= 2.2.2, < 4.0)
40
+ regexp_parser (>= 1.8, < 3.0)
41
+ rexml
42
+ rubocop-ast (>= 1.9.1, < 2.0)
43
+ ruby-progressbar (~> 1.7)
44
+ unicode-display_width (>= 1.4.0, < 3.0)
45
+ rubocop-ast (1.11.0)
46
+ parser (>= 3.0.1.1)
47
+ ruby-progressbar (1.11.0)
48
+ solargraph (0.43.0)
49
+ backport (~> 1.2)
50
+ benchmark
51
+ bundler (>= 1.17.2)
52
+ diff-lcs (~> 1.4)
53
+ e2mmap
54
+ jaro_winkler (~> 1.5)
55
+ kramdown (~> 2.3)
56
+ kramdown-parser-gfm (~> 1.1)
57
+ parser (~> 3.0)
58
+ reverse_markdown (>= 1.0.5, < 3)
59
+ rubocop (>= 0.52)
60
+ thor (~> 1.0)
61
+ tilt (~> 2.0)
62
+ yard (~> 0.9, >= 0.9.24)
63
+ thor (1.1.0)
64
+ tilt (2.0.10)
65
+ unicode-display_width (2.0.0)
66
+ yard (0.9.26)
67
+
68
+ PLATFORMS
69
+ x86_64-darwin-20
70
+
71
+ DEPENDENCIES
72
+ rake (~> 12.0)
73
+ solargraph_test_coverage!
74
+
75
+ BUNDLED WITH
76
+ 2.2.12
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Cameron
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,60 @@
1
+ # SolargraphTestCoverage
2
+
3
+ Solargraph Plugin that provides a diagnostic reporter for unit-test coverage.
4
+
5
+ Currently only works with RSpec.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'solargraph_test_coverage'
13
+ ```
14
+
15
+ Then add this to your `.solargraph.yml` config:
16
+ ```yaml
17
+ plugins:
18
+ - solargraph_test_coverage
19
+ reporters:
20
+ - test_coverage
21
+ ```
22
+
23
+ If you are using a `spec/rails_helper.rb` file, you will need to change:
24
+ ```ruby
25
+ require "spec_helper"
26
+ ```
27
+
28
+ to
29
+
30
+ ```ruby
31
+ require_relative "spec_helper"
32
+ ```
33
+
34
+ And then execute:
35
+
36
+ $ bundle install
37
+
38
+ Or install it yourself as:
39
+
40
+ $ gem install solargraph_test_coverage
41
+
42
+ ## Usage
43
+
44
+ With solargraph running and connected to your text editor, you should see diagnostic messages for test coverage.
45
+
46
+ Currently there are four different messages:
47
+ - Line is not covered
48
+ - Branch is not covered (With a note if it's the 'THEN' or 'ELSE' branch)
49
+ - Spec is failing (Error message will be on line 1)
50
+ - Spec cannot be found (Error message will be on line 1)
51
+
52
+
53
+ ## Contributing
54
+
55
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ckolkey/solargraph_test_coverage.
56
+
57
+
58
+ ## License
59
+
60
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolargraphTestCoverage
4
+ # Adapted from SimpleCov - Small class that turns branch coverage data into something easier to work with
5
+ class Branch
6
+ class << self
7
+ #
8
+ # Builds an array of Branch objects for every branch in results hash.
9
+ #
10
+ # @return [Array]
11
+ #
12
+ def build_from(results)
13
+ results.fetch(:branches, {}).flat_map do |condition, branches|
14
+ _condition_type, _condition_id, condition_start_line, * = condition
15
+
16
+ branches.map do |branch_data, hit_count|
17
+ type, _id, start_line, _start_col, end_line, _end_col = branch_data
18
+
19
+ new(start_line: start_line, end_line: end_line, coverage: hit_count,
20
+ inline: start_line == condition_start_line, type: type)
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ attr_reader :start_line, :end_line, :coverage, :type
27
+
28
+ def initialize(start_line:, end_line:, coverage:, inline:, type:)
29
+ @start_line = start_line
30
+ @end_line = end_line
31
+ @coverage = coverage
32
+ @inline = inline
33
+ @type = type
34
+ end
35
+
36
+ #
37
+ # Predicate method for @inline instance variable
38
+ #
39
+ # @return [Boolean]
40
+ #
41
+ def inline?
42
+ @inline
43
+ end
44
+
45
+ #
46
+ # Return true if there is relevant count defined > 0
47
+ #
48
+ # @return [Boolean]
49
+ #
50
+ def covered?
51
+ coverage.positive?
52
+ end
53
+
54
+ #
55
+ # The line on which we want to report the coverage
56
+ #
57
+ # Usually we choose the line above the start of the branch (so that it shows up
58
+ # at if/else) because that
59
+ # * highlights the condition
60
+ # * makes it distinguishable if the first line of the branch is an inline branch
61
+ # (see the nested_branches fixture)
62
+ #
63
+ # @return [Integer]
64
+ #
65
+ def report_line
66
+ inline? ? start_line : start_line - 1
67
+ end
68
+
69
+ #
70
+ # Return array with coverage count and badge
71
+ #
72
+ # @return [Hash]
73
+ #
74
+ def report
75
+ { type: type, line: report_line }
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolargraphTestCoverage
4
+ # https://stackoverflow.com/questions/1076257/returning-data-from-forked-processes
5
+ # When called with a block, runs the content of said block in a new (forked) process
6
+ # the return value of the process/block can be captured and used in parent process
7
+ class ForkProcess
8
+ #
9
+ # Executes block in forked process, and captures returned value of that block
10
+ # Returns result of block
11
+ #
12
+ # @return [Object]
13
+ #
14
+ def self.run
15
+ read, write = IO.pipe
16
+
17
+ pid = fork do
18
+ read.close
19
+ result = yield
20
+ Marshal.dump(result, write)
21
+ exit!(0) # skips exit handlers.
22
+ end
23
+
24
+ write.close
25
+ result = read.read
26
+ Process.wait(pid)
27
+ raise ChildFailedError if result.nil? || result.empty?
28
+
29
+ Marshal.load(result)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolargraphTestCoverage
4
+ module Helpers
5
+ #
6
+ # Attempts to find the corrosponding unit test file
7
+ # TODO: This could be a bit more robust, supporting gems (/lib/) and
8
+ # minitest (/test/)
9
+ #
10
+ # @return [String]
11
+ #
12
+ def locate_test_file(source)
13
+ source.location.filename.sub('/app/', '/spec/').sub('.rb', '_spec.rb')
14
+ end
15
+
16
+ #
17
+ # Runs RSpec on test file in a child process
18
+ # Returns coverage results for current working file
19
+ # RSpec::Core::Runner.run will return 0 if the test file passes, and 1 if it does not.
20
+ #
21
+ # @return [Hash]
22
+ #
23
+ def run_rspec(source, test_file)
24
+ ForkProcess.run do
25
+ Coverage.start(lines: true, branches: true)
26
+ exit_code = RSpec::Core::Runner.run([test_file])
27
+ Coverage.result.fetch(source.location.filename, {}).merge({ test_status: exit_code })
28
+ end
29
+ end
30
+
31
+ #
32
+ # Adapted from SingleCov
33
+ # Coverage returns nil for untestable lines (like do, end, if keywords)
34
+ # otherwise returns int showing how many times a line was called
35
+ #
36
+ # [nil, 1, 0, 1, 0] -> [3, 5]
37
+ #
38
+ # @return [Array]
39
+ #
40
+ def uncovered_lines(results)
41
+ results.fetch(:lines)
42
+ .each_with_index
43
+ .select { |c, _| c == 0 }
44
+ .map { |_, i| i }
45
+ .compact
46
+ end
47
+
48
+ #
49
+ # Builds a new Branch object for each branch tested from results hash
50
+ # Then removes branches which have test coverage
51
+ #
52
+ # @return [Array]
53
+ #
54
+ def uncovered_branches(results)
55
+ Branch.build_from(results).reject(&:covered?)
56
+ end
57
+
58
+ #
59
+ # Only called once, when gem is loaded
60
+ # Preloads rails via spec/rails_helper if Rails isn't already defined
61
+ # This gives us a nice speed-boost when running test in child process
62
+ #
63
+ # We rescue the LoadError since Solargraph would catch it otherwise,
64
+ # and not load the plugin at all.
65
+ #
66
+ # If Coverage was started in Rails/Spec helper by SimpleCov,
67
+ # calling Coverage.result after requiring stops and resets it.
68
+ #
69
+ # This is a bit experimental - I'm not sure if there will be downstream side-effects
70
+ # from having Rails preloaded, but... we'll see :)
71
+ #
72
+ def self.preload_rails!
73
+ return if defined?(Rails)
74
+ return unless File.file?('spec/rails_helper.rb')
75
+
76
+ require File.expand_path("spec/rails_helper")
77
+ Coverage.result(stop: true, clear: true) if Coverage.running?
78
+ rescue LoadError => e
79
+ Solargraph::Logging.logger.warn "LoadError when trying to require 'rails_helper'"
80
+ Solargraph::Logging.logger.warn "[#{e.class}] #{e.message}"
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ # test_coverage reporter for Solargraph
4
+ module SolargraphTestCoverage
5
+ class TestCoverageReporter < Solargraph::Diagnostics::Base
6
+ include Helpers
7
+
8
+ #
9
+ # LSP Diagnostic method
10
+ #
11
+ # @return [Array]
12
+ #
13
+ def diagnose(source, _api_map)
14
+ return [] if source.code.empty? || !source.location.filename.include?('/app/')
15
+
16
+ test_file = locate_test_file(source)
17
+ return [no_test_file_error(source, test_file)] unless File.file?(test_file)
18
+
19
+ results = run_rspec(source, test_file)
20
+ lines = uncovered_lines(results).map { |line| line_coverage_warning(source, line) }
21
+ branches = uncovered_branches(results).map { |branch| branch_coverage_warning(source, branch.report) }
22
+ status = results[:test_status].zero? ? [] : [test_failing_error(source)]
23
+
24
+ lines + branches + status
25
+ rescue ChildFailedError
26
+ []
27
+ end
28
+
29
+ private
30
+
31
+ #
32
+ # Creates LSP warning message for missing line coverage
33
+ #
34
+ # @return [Hash]
35
+ #
36
+ def line_coverage_warning(source, line)
37
+ {
38
+ range: Solargraph::Range.from_to(line, 0, line, source.code.lines[line].length).to_hash,
39
+ severity: Solargraph::Diagnostics::Severities::WARNING,
40
+ source: 'TestCoverage',
41
+ message: 'Line is missing test coverage'
42
+ }
43
+ end
44
+
45
+ #
46
+ # Creates LSP warning message for missing branch coverage
47
+ # We need to correct the line number (-1), since the coverage module
48
+ # starts counting lines at 1, while the LSP (source.code.line) is an array
49
+ # with an index starting at 0
50
+ #
51
+ # @return [Hash]
52
+ #
53
+ def branch_coverage_warning(source, report)
54
+ {
55
+ range: Solargraph::Range.from_to(report[:line] - 1, 0, report[:line] - 1, source.code.lines[report[:line] - 1].length).to_hash,
56
+ severity: Solargraph::Diagnostics::Severities::WARNING,
57
+ source: 'TestCoverage',
58
+ message: "'#{report[:type].upcase}' branch is missing test coverage"
59
+ }
60
+ end
61
+
62
+ #
63
+ # Creates LSP error message if test is failing
64
+ #
65
+ # @return [Hash]
66
+ #
67
+ def test_failing_error(source)
68
+ {
69
+ range: Solargraph::Range.from_to(0, 0, 0, source.code.lines[0].length).to_hash,
70
+ severity: Solargraph::Diagnostics::Severities::ERROR,
71
+ source: 'TestCoverage',
72
+ message: "Unit Test is currently failing."
73
+ }
74
+ end
75
+
76
+ #
77
+ # Creates LSP error message if no test file can be found
78
+ #
79
+ # @return [Hash]
80
+ #
81
+ def no_test_file_error(source, test_file_location)
82
+ {
83
+ range: Solargraph::Range.from_to(0, 0, 0, source.code.lines[0].length).to_hash,
84
+ severity: Solargraph::Diagnostics::Severities::ERROR,
85
+ source: 'TestCoverage',
86
+ message: "No unit test file found at #{test_file_location}"
87
+ }
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,3 @@
1
+ module SolargraphTestCoverage
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,25 @@
1
+ require 'solargraph_test_coverage/version'
2
+ require 'solargraph_test_coverage/branch'
3
+ require 'solargraph_test_coverage/fork_process'
4
+ require 'solargraph_test_coverage/helpers'
5
+ require 'solargraph_test_coverage/test_coverage_reporter'
6
+
7
+ require 'solargraph'
8
+ require 'rspec/core'
9
+ require 'coverage'
10
+ require 'pry-byebug'
11
+
12
+ # TODO
13
+ # - Finding the right file could use some work
14
+ # - Config Options for different errors (line, branch, test missing, test failing)
15
+ # - Minitest/Cucumber Support
16
+ # - app/lib support
17
+ # - filter out stuff like controllers that wouldn't have tests
18
+ # - Publish Gem to Rubygems
19
+
20
+ module SolargraphTestCoverage
21
+ class ChildFailedError < StandardError; end
22
+ Helpers.preload_rails!
23
+
24
+ Solargraph::Diagnostics.register 'test_coverage', TestCoverageReporter
25
+ end
@@ -0,0 +1,33 @@
1
+ require_relative 'lib/solargraph_test_coverage/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'solargraph_test_coverage'
5
+ spec.version = SolargraphTestCoverage::VERSION
6
+ spec.authors = ['Cameron Kolkey']
7
+ spec.email = ['Cameron.Kolkey@gmail.com']
8
+
9
+ spec.summary = 'Solargraph Plugin'
10
+ spec.description = 'Solargraph Plugin that reports line/branch coverage from unit tests'
11
+ spec.homepage = 'https://github.com/ckolkey/solargraph_test_coverage'
12
+ spec.license = 'MIT'
13
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
14
+
15
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = spec.homepage
19
+ spec.metadata['changelog_uri'] = spec.homepage
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|bin)/}) }
25
+ end
26
+
27
+ spec.bindir = 'exe'
28
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ['lib']
30
+
31
+ spec.add_runtime_dependency 'solargraph', '~> 0.40', '> 0.40'
32
+ spec.add_runtime_dependency 'rspec-core', '~> 3.10', '>= 3.10.0'
33
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: solargraph_test_coverage
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Cameron Kolkey
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-08-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: solargraph
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.40'
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '0.40'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.40'
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '0.40'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rspec-core
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 3.10.0
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '3.10'
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 3.10.0
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: '3.10'
53
+ description: Solargraph Plugin that reports line/branch coverage from unit tests
54
+ email:
55
+ - Cameron.Kolkey@gmail.com
56
+ executables: []
57
+ extensions: []
58
+ extra_rdoc_files: []
59
+ files:
60
+ - ".gitignore"
61
+ - ".ruby-version"
62
+ - Gemfile
63
+ - Gemfile.lock
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - lib/solargraph_test_coverage.rb
68
+ - lib/solargraph_test_coverage/branch.rb
69
+ - lib/solargraph_test_coverage/fork_process.rb
70
+ - lib/solargraph_test_coverage/helpers.rb
71
+ - lib/solargraph_test_coverage/test_coverage_reporter.rb
72
+ - lib/solargraph_test_coverage/version.rb
73
+ - solargraph_test_coverage.gemspec
74
+ homepage: https://github.com/ckolkey/solargraph_test_coverage
75
+ licenses:
76
+ - MIT
77
+ metadata:
78
+ allowed_push_host: https://rubygems.org
79
+ homepage_uri: https://github.com/ckolkey/solargraph_test_coverage
80
+ source_code_uri: https://github.com/ckolkey/solargraph_test_coverage
81
+ changelog_uri: https://github.com/ckolkey/solargraph_test_coverage
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 2.3.0
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubygems_version: 3.0.3
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Solargraph Plugin
101
+ test_files: []