solargraph_test_coverage 0.1.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.
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: []