solargraph-rspec 0.1.1 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -1
- data/README.md +5 -2
- data/codecov.yml +13 -0
- data/lib/solargraph/rspec/convention.rb +20 -70
- data/lib/solargraph/rspec/correctors/base.rb +26 -3
- data/lib/solargraph/rspec/correctors/context_block_methods_corrector.rb +1 -3
- data/lib/solargraph/rspec/correctors/context_block_namespace_corrector.rb +11 -14
- data/lib/solargraph/rspec/correctors/described_class_corrector.rb +12 -11
- data/lib/solargraph/rspec/correctors/dsl_methods_corrector.rb +49 -20
- data/lib/solargraph/rspec/correctors/example_and_hook_blocks_binding_corrector.rb +20 -30
- data/lib/solargraph/rspec/correctors/let_methods_corrector.rb +12 -14
- data/lib/solargraph/rspec/correctors/subject_method_corrector.rb +44 -4
- data/lib/solargraph/rspec/pin_factory.rb +100 -0
- data/lib/solargraph/rspec/spec_walker/fake_let_method.rb +35 -0
- data/lib/solargraph/rspec/spec_walker/full_constant_name.rb +29 -0
- data/lib/solargraph/rspec/spec_walker/node_types.rb +82 -0
- data/lib/solargraph/rspec/spec_walker/rspec_context_namespace.rb +56 -0
- data/lib/solargraph/rspec/spec_walker.rb +63 -101
- data/lib/solargraph/rspec/version.rb +1 -1
- data/lib/solargraph/rspec/walker.rb +11 -35
- metadata +8 -5
- data/lib/solargraph/rspec/correctors/implicit_subject_method_corrector.rb +0 -48
- data/lib/solargraph/rspec/correctors/walker_base.rb +0 -27
- data/lib/solargraph/rspec/util.rb +0 -77
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 25d0ca1f34e0cf80057b86a412ec10cbacba388a96bd5b5e7b93f64457616e5a
|
4
|
+
data.tar.gz: d1b4b825f9df08a3333bab32d2af05a9cc6a48cd7903f5b4504baba1e775a960
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d7efb9da09a862654e5bb4fbd70bb983230cae9303e98ebc487cb0f00afe752ba8c936513dc23aac153e99f49d607b93111aada2f235fb47fdbeefcb81a0acb
|
7
|
+
data.tar.gz: aa9563e0d56a8ab37b45a739f6394e47e7dd597bc59bfb205a043ed41d9b5c47bc08b7a8184225ed75f2840bd57aeedd96ed05f325d32700c54e81aafb3e39d3
|
data/CHANGELOG.md
CHANGED
@@ -7,7 +7,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
-
|
10
|
+
|
11
|
+
## [0.2.1] - 2024-06-09
|
12
|
+
|
13
|
+
### Added
|
14
|
+
|
15
|
+
- Documentation for `RSpec::ExampleGroups` DSL methods like `it`, `fit`, `example` etc.
|
16
|
+
|
17
|
+
### Fixed
|
18
|
+
|
19
|
+
- Fix nameless `subject` method completion inside nested `context` blocks
|
20
|
+
- (Hack-ish) Fix `described_class` type collision when `RSpec.describe SomeClassWithoutNamespace`
|
21
|
+
|
22
|
+
## [0.2.0] - 2024-05-20
|
23
|
+
|
24
|
+
### Added
|
25
|
+
|
26
|
+
- `let` and `subject` type inference 🚀 (Resolves: [Issue #1](https://github.com/lekemula/solargraph-rspec/issues/1))
|
27
|
+
|
28
|
+
### Changed
|
29
|
+
|
30
|
+
- Migrate from `parser` gem to using ruby's built-in RubyVM::AbstractSyntaxTree ([see why](https://github.com/castwide/solargraph/issues/522#issuecomment-993016664))
|
31
|
+
|
32
|
+
### Fixed
|
33
|
+
|
34
|
+
- Fix subject without name block completion: `subject { ... }`
|
35
|
+
- Fix subject return class overlap with `Rspec::ExampleGroups::` when class has no namespace
|
11
36
|
|
12
37
|
## [0.1.1] - 2024-05-13
|
13
38
|
|
data/README.md
CHANGED
@@ -7,15 +7,18 @@
|
|
7
7
|
|
8
8
|
RSpec is a testing framework of choice for many Ruby developers. But at the same time is highly dynamic and heavily relying on metaprogramming making it hard to provide accurate code completion and type inference.
|
9
9
|
|
10
|
-
This gem aims to provide
|
10
|
+
This gem aims to provide better support for RSpec in Solargraph and it supports the following features:
|
11
11
|
- `describe` and `it` methods completion
|
12
12
|
- memoized `let` and `let!` methods completion
|
13
13
|
- implicit and explicit `subject` methods
|
14
14
|
- `described_class` with appropriate type inference
|
15
15
|
- `RSpec::Matchers` methods completion
|
16
|
+
- type inference 🚀
|
16
17
|
- and more to come...
|
17
18
|
|
18
|
-
|
19
|
+
![solargraph-rspec-with-types](https://github.com/lekemula/solargraph-rspec/assets/9197495/077e74f8-a800-4e90-8922-fa5351adcda3)
|
20
|
+
![solargraph-rspec-with-types-vs-code](https://github.com/lekemula/solargraph-rspec/assets/9197495/6a942460-256d-46ca-82de-9869a65309ec)
|
21
|
+
|
19
22
|
|
20
23
|
## Installation
|
21
24
|
|
data/codecov.yml
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# https://docs.codecov.com/docs/common-recipe-list
|
2
|
+
coverage:
|
3
|
+
status:
|
4
|
+
project: #add everything under here, more options at https://docs.codecov.com/docs/commit-status
|
5
|
+
default:
|
6
|
+
# basic
|
7
|
+
target: auto #default
|
8
|
+
threshold: 1%
|
9
|
+
base: auto
|
10
|
+
informational: true
|
11
|
+
patch:
|
12
|
+
default:
|
13
|
+
informational: true
|
@@ -8,9 +8,8 @@ require_relative 'correctors/described_class_corrector'
|
|
8
8
|
require_relative 'correctors/let_methods_corrector'
|
9
9
|
require_relative 'correctors/subject_method_corrector'
|
10
10
|
require_relative 'correctors/context_block_methods_corrector'
|
11
|
-
require_relative 'correctors/implicit_subject_method_corrector'
|
12
11
|
require_relative 'correctors/dsl_methods_corrector'
|
13
|
-
require_relative '
|
12
|
+
require_relative 'pin_factory'
|
14
13
|
|
15
14
|
module Solargraph
|
16
15
|
module Rspec
|
@@ -50,6 +49,17 @@ module Solargraph
|
|
50
49
|
include_context
|
51
50
|
].freeze
|
52
51
|
|
52
|
+
# @type [Array<Class<Correctors::Base>>]
|
53
|
+
CORRECTOR_CLASSES = [
|
54
|
+
Correctors::ContextBlockMethodsCorrector,
|
55
|
+
Correctors::ContextBlockNamespaceCorrector,
|
56
|
+
Correctors::DescribedClassCorrector,
|
57
|
+
Correctors::DslMethodsCorrector,
|
58
|
+
Correctors::ExampleAndHookBlocksBindingCorrector,
|
59
|
+
Correctors::LetMethodsCorrector,
|
60
|
+
Correctors::SubjectMethodCorrector
|
61
|
+
].freeze
|
62
|
+
|
53
63
|
# Provides completion for RSpec DSL and helper methods.
|
54
64
|
# - `describe` and `context` blocks
|
55
65
|
# - `let` and `let!` methods
|
@@ -105,77 +115,17 @@ module Solargraph
|
|
105
115
|
|
106
116
|
rspec_walker = SpecWalker.new(source_map: source_map, config: config)
|
107
117
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
Correctors::ExampleAndHookBlocksBindingCorrector.new(
|
116
|
-
namespace_pins: namespace_pins,
|
117
|
-
rspec_walker: rspec_walker
|
118
|
-
).correct(source_map) do |pins_to_add|
|
119
|
-
pins += pins_to_add
|
120
|
-
end
|
121
|
-
|
122
|
-
# @type [Pin::Method, nil]
|
123
|
-
described_class_pin = nil
|
124
|
-
Correctors::DescribedClassCorrector.new(namespace_pins: namespace_pins, rspec_walker: rspec_walker).correct(
|
125
|
-
source_map
|
126
|
-
) do |pins_to_add|
|
127
|
-
described_class_pin = pins_to_add.first
|
128
|
-
pins += pins_to_add
|
129
|
-
end
|
130
|
-
|
131
|
-
Correctors::LetMethodsCorrector.new(namespace_pins: namespace_pins, rspec_walker: rspec_walker).correct(
|
132
|
-
source_map
|
133
|
-
) do |pins_to_add|
|
134
|
-
pins += pins_to_add
|
135
|
-
end
|
136
|
-
|
137
|
-
# @type [Pin::Method, nil]
|
138
|
-
subject_pin = nil
|
139
|
-
Correctors::SubjectMethodCorrector.new(namespace_pins: namespace_pins, rspec_walker: rspec_walker).correct(
|
140
|
-
source_map
|
141
|
-
) do |pins_to_add|
|
142
|
-
subject_pin = pins_to_add.first
|
143
|
-
pins += pins_to_add
|
144
|
-
end
|
145
|
-
|
146
|
-
Correctors::ContextBlockMethodsCorrector.new(
|
147
|
-
namespace_pins: namespace_pins,
|
148
|
-
rspec_walker: rspec_walker
|
149
|
-
).correct(source_map) do |pins_to_add|
|
150
|
-
pins += pins_to_add
|
151
|
-
end
|
152
|
-
|
153
|
-
Correctors::DslMethodsCorrector.new(
|
154
|
-
namespace_pins: namespace_pins,
|
155
|
-
rspec_walker: rspec_walker,
|
156
|
-
config: config
|
157
|
-
).correct(
|
158
|
-
source_map
|
159
|
-
) do |pins_to_add|
|
160
|
-
pins += pins_to_add
|
118
|
+
CORRECTOR_CLASSES.each do |corrector_class|
|
119
|
+
corrector_class.new(
|
120
|
+
namespace_pins: namespace_pins,
|
121
|
+
rspec_walker: rspec_walker,
|
122
|
+
added_pins: pins
|
123
|
+
).correct(source_map)
|
161
124
|
end
|
162
125
|
|
163
126
|
rspec_walker.walk!
|
164
127
|
pins += namespace_pins
|
165
128
|
|
166
|
-
# Implicit subject
|
167
|
-
if !subject_pin && described_class_pin
|
168
|
-
Correctors::ImplicitSubjectMethodCorrector.new(
|
169
|
-
namespace_pins: namespace_pins,
|
170
|
-
described_class_pin: described_class_pin
|
171
|
-
).correct(
|
172
|
-
source_map
|
173
|
-
) do |pins_to_add|
|
174
|
-
subject_pin = pins_to_add.first
|
175
|
-
pins += pins_to_add
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
129
|
if pins.any?
|
180
130
|
Solargraph.logger.debug(
|
181
131
|
"[RSpec] added #{pins.map(&:inspect)} to #{source_map.filename}"
|
@@ -199,7 +149,7 @@ module Solargraph
|
|
199
149
|
# @return [Array<Pin::Base>]
|
200
150
|
def include_helper_pins(helper_modules: HELPER_MODULES)
|
201
151
|
helper_modules.map do |helper_module|
|
202
|
-
|
152
|
+
PinFactory.build_module_include(
|
203
153
|
root_example_group_namespace_pin,
|
204
154
|
helper_module,
|
205
155
|
root_example_group_namespace_pin.location
|
@@ -216,7 +166,7 @@ module Solargraph
|
|
216
166
|
def root_example_group_namespace_pin
|
217
167
|
Solargraph::Pin::Namespace.new(
|
218
168
|
name: ROOT_NAMESPACE,
|
219
|
-
location:
|
169
|
+
location: PinFactory.dummy_location('lib/rspec/core/example_group.rb')
|
220
170
|
)
|
221
171
|
end
|
222
172
|
end
|
@@ -9,13 +9,22 @@ module Solargraph
|
|
9
9
|
# @return [Array<Solargraph::Pin::Namespace>]
|
10
10
|
attr_reader :namespace_pins
|
11
11
|
|
12
|
+
# @return [Solargraph::Rspec::SpecWalker]
|
13
|
+
attr_reader :rspec_walker
|
14
|
+
|
15
|
+
# @return [Array<Solargraph::Pin::Base]
|
16
|
+
attr_reader :added_pins
|
17
|
+
|
12
18
|
# @param namespace_pins [Array<Solargraph::Pin::Base>]
|
13
|
-
|
19
|
+
# @param rspec_walker [Solargraph::Rspec::SpecWalker]
|
20
|
+
# @param added_pins [Array<Solargraph::Pin::Base>]
|
21
|
+
def initialize(namespace_pins:, rspec_walker:, added_pins: [])
|
14
22
|
@namespace_pins = namespace_pins
|
23
|
+
@rspec_walker = rspec_walker
|
24
|
+
@added_pins = added_pins
|
15
25
|
end
|
16
26
|
|
17
27
|
# @param _source_map [Solargraph::SourceMap]
|
18
|
-
# @yield [Array<Solargraph::Pin::Base>] Pins to be added to the source map
|
19
28
|
# @return [void]
|
20
29
|
def correct(_source_map)
|
21
30
|
raise NotImplementedError
|
@@ -23,11 +32,25 @@ module Solargraph
|
|
23
32
|
|
24
33
|
private
|
25
34
|
|
35
|
+
# @param pin [Solargraph::Pin::Base, nil]
|
36
|
+
# @return [void]
|
37
|
+
def add_pin(pin)
|
38
|
+
return unless pin
|
39
|
+
|
40
|
+
added_pins.push(pin)
|
41
|
+
end
|
42
|
+
|
43
|
+
# @param pins [Array<Solargraph::Pin::Base>]
|
44
|
+
# @return [void]
|
45
|
+
def add_pins(*pins)
|
46
|
+
added_pins.concat(pins.flatten.compact)
|
47
|
+
end
|
48
|
+
|
26
49
|
# @return [Solargraph::Pin::Namespace]
|
27
50
|
def root_example_group_namespace_pin
|
28
51
|
Solargraph::Pin::Namespace.new(
|
29
52
|
name: ROOT_NAMESPACE,
|
30
|
-
location:
|
53
|
+
location: PinFactory.dummy_location('lib/rspec/core/example_group.rb')
|
31
54
|
)
|
32
55
|
end
|
33
56
|
|
@@ -6,7 +6,7 @@ module Solargraph
|
|
6
6
|
module Rspec
|
7
7
|
module Correctors
|
8
8
|
# A corrector that corrects pure ruby method blocks namespace defined inside describe/context blocks.
|
9
|
-
class ContextBlockMethodsCorrector <
|
9
|
+
class ContextBlockMethodsCorrector < Base
|
10
10
|
# @param source_map [Solargraph::SourceMap]
|
11
11
|
def correct(source_map)
|
12
12
|
rspec_walker.after_walk do
|
@@ -28,8 +28,6 @@ module Solargraph
|
|
28
28
|
comments: pin.comments
|
29
29
|
)
|
30
30
|
end
|
31
|
-
|
32
|
-
yield [] if block_given?
|
33
31
|
end
|
34
32
|
end
|
35
33
|
end
|
@@ -1,18 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
3
|
+
require_relative 'base'
|
4
4
|
|
5
5
|
module Solargraph
|
6
6
|
module Rspec
|
7
7
|
module Correctors
|
8
|
-
#
|
9
|
-
class ContextBlockNamespaceCorrector <
|
8
|
+
# RSpec generates a namespace class for each context block. This corrector add the pins for those namespaces.
|
9
|
+
class ContextBlockNamespaceCorrector < Base
|
10
10
|
# @param source_map [Solargraph::SourceMap]
|
11
11
|
def correct(source_map)
|
12
|
-
|
13
|
-
|
12
|
+
# @param location_range [Solargraph::Range]
|
13
|
+
rspec_walker.on_each_context_block do |namespace_name, location_range|
|
14
|
+
original_block_pin = source_map.locate_block_pin(location_range.start.line, location_range.start.column)
|
14
15
|
original_block_pin_index = source_map.pins.index(original_block_pin)
|
15
|
-
location =
|
16
|
+
location = PinFactory.build_location(location_range, source_map.filename)
|
16
17
|
|
17
18
|
# Define a dynamic module for the example group block
|
18
19
|
# Example:
|
@@ -36,7 +37,7 @@ module Solargraph
|
|
36
37
|
|
37
38
|
# Include DSL methods in the example group block
|
38
39
|
# TOOD: This does not work on solagraph! Class methods are not included from parent class.
|
39
|
-
namespace_extend_pin =
|
40
|
+
namespace_extend_pin = PinFactory.build_module_extend(
|
40
41
|
namespace_pin,
|
41
42
|
root_example_group_namespace_pin.name,
|
42
43
|
location
|
@@ -44,19 +45,15 @@ module Solargraph
|
|
44
45
|
|
45
46
|
# Include parent example groups to share let definitions
|
46
47
|
parent_namespace_name = namespace_name.split('::')[0..-2].join('::')
|
47
|
-
namespace_include_pin =
|
48
|
+
namespace_include_pin = PinFactory.build_module_include(
|
48
49
|
namespace_pin,
|
49
50
|
parent_namespace_name,
|
50
51
|
location
|
51
52
|
)
|
52
53
|
|
53
54
|
namespace_pins << namespace_pin
|
54
|
-
|
55
|
-
|
56
|
-
namespace_include_pin,
|
57
|
-
namespace_extend_pin
|
58
|
-
]
|
59
|
-
end
|
55
|
+
|
56
|
+
add_pins(namespace_extend_pin, namespace_include_pin)
|
60
57
|
end
|
61
58
|
end
|
62
59
|
end
|
@@ -1,35 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
3
|
+
require_relative 'base'
|
4
4
|
|
5
5
|
module Solargraph
|
6
6
|
module Rspec
|
7
7
|
module Correctors
|
8
|
-
|
8
|
+
# Defines `described_class` method in the example group block
|
9
|
+
class DescribedClassCorrector < Base
|
9
10
|
# @param source_map [Solargraph::SourceMap]
|
10
11
|
# @return [void]
|
11
12
|
def correct(_source_map)
|
12
|
-
rspec_walker.on_described_class do |
|
13
|
-
namespace_pin = closest_namespace_pin(namespace_pins,
|
13
|
+
rspec_walker.on_described_class do |described_class_name, location_range|
|
14
|
+
namespace_pin = closest_namespace_pin(namespace_pins, location_range.start.line)
|
14
15
|
next unless namespace_pin
|
15
16
|
|
16
|
-
described_class_pin = rspec_described_class_method(namespace_pin,
|
17
|
-
|
17
|
+
described_class_pin = rspec_described_class_method(namespace_pin, location_range, described_class_name)
|
18
|
+
add_pin(described_class_pin)
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
21
22
|
private
|
22
23
|
|
23
24
|
# @param namespace [Pin::Namespace]
|
24
|
-
# @param
|
25
|
+
# @param location_range [Solargraph::Range]
|
25
26
|
# @param described_class_name [String]
|
26
27
|
# @return [Pin::Method, nil]
|
27
|
-
def rspec_described_class_method(namespace,
|
28
|
-
|
28
|
+
def rspec_described_class_method(namespace, location_range, described_class_name)
|
29
|
+
PinFactory.build_public_method(
|
29
30
|
namespace,
|
30
31
|
'described_class',
|
31
|
-
types: ["Class
|
32
|
-
location:
|
32
|
+
types: ["Class<::#{described_class_name}>"],
|
33
|
+
location: PinFactory.build_location(location_range, namespace.filename),
|
33
34
|
scope: :instance
|
34
35
|
)
|
35
36
|
end
|
@@ -1,44 +1,47 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
3
|
+
require_relative 'base'
|
4
|
+
require 'yard'
|
4
5
|
|
5
6
|
module Solargraph
|
6
7
|
module Rspec
|
7
8
|
module Correctors
|
8
|
-
|
9
|
-
|
10
|
-
# @
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
# Includes DSL method helpers in the example group block for completion (ie. it, before, let, subject, etc.)
|
10
|
+
class DslMethodsCorrector < Base
|
11
|
+
# @return [Array<YARD::CodeObjects::Base>]
|
12
|
+
def self.rspec_yardoc_tags
|
13
|
+
@rspec_yardoc_tags ||= begin
|
14
|
+
spec = Gem::Specification.find_by_name('rspec-core')
|
15
|
+
require_paths = spec.require_paths.map { |path| File.join(spec.full_gem_path, path) }
|
16
|
+
Solargraph.logger.debug "[RSpec] Loading YARD registry for rspec-core from #{require_paths}"
|
17
|
+
YARD::Registry.load(require_paths, true)
|
18
|
+
YARD::Registry.all
|
19
|
+
end
|
15
20
|
end
|
16
21
|
|
17
22
|
# @param source_map [Solargraph::SourceMap]
|
18
23
|
# @return [void]
|
19
24
|
def correct(_source_map)
|
20
25
|
rspec_walker.after_walk do
|
21
|
-
|
22
|
-
|
23
|
-
|
26
|
+
namespace_pins.each do |namespace_pin|
|
27
|
+
add_pins(context_dsl_methods(namespace_pin))
|
28
|
+
add_pins(methods_with_example_binding(namespace_pin))
|
24
29
|
end
|
25
30
|
end
|
26
31
|
end
|
27
32
|
|
28
33
|
private
|
29
34
|
|
30
|
-
# @return [Solargraph::Rspec::Config]
|
31
|
-
attr_reader :config
|
32
|
-
|
33
35
|
# RSpec executes example and hook blocks (eg. it, before, after)in the context of the example group.
|
34
|
-
# @yieldsef changes the binding of the block to correct class.
|
36
|
+
# Tag @yieldsef changes the binding of the block to correct class.
|
35
37
|
# @return [Array<Solargraph::Pin::Method>]
|
36
|
-
def
|
38
|
+
def methods_with_example_binding(namespace_pin)
|
37
39
|
rspec_context_block_methods.map do |method|
|
38
|
-
|
40
|
+
# TODO: Add location from YARD registry and documentation for other methods not just example group methods.
|
41
|
+
PinFactory.build_public_method(
|
39
42
|
namespace_pin,
|
40
43
|
method.to_s,
|
41
|
-
comments: ["@yieldself [#{namespace_pin.path}]"],
|
44
|
+
comments: [example_group_documentation(method), "@yieldself [#{namespace_pin.path}]"],
|
42
45
|
scope: :class
|
43
46
|
)
|
44
47
|
end
|
@@ -48,9 +51,9 @@ module Solargraph
|
|
48
51
|
# Fix this once Solargraph supports extending class methods.
|
49
52
|
# @param namespace_pin [Solargraph::Pin::Base]
|
50
53
|
# @return [Array<Solargraph::Pin::Base>]
|
51
|
-
def
|
54
|
+
def context_dsl_methods(namespace_pin)
|
52
55
|
Rspec::CONTEXT_METHODS.map do |method|
|
53
|
-
|
56
|
+
PinFactory.build_public_method(
|
54
57
|
namespace_pin,
|
55
58
|
method.to_s,
|
56
59
|
scope: :class
|
@@ -58,10 +61,36 @@ module Solargraph
|
|
58
61
|
end
|
59
62
|
end
|
60
63
|
|
64
|
+
# @param method [String]
|
65
|
+
# @return [String]
|
66
|
+
def example_group_documentation(method)
|
67
|
+
return unless Rspec::EXAMPLE_METHODS.include?(method)
|
68
|
+
|
69
|
+
yardoc = rspec_yardoc_tags_at("RSpec::Core::ExampleGroup.#{method}")
|
70
|
+
|
71
|
+
unless yardoc
|
72
|
+
Solargraph.logger.warn "[RSpec] YARD documentation not found for RSpec::Core::ExampleGroup.#{method}"
|
73
|
+
return
|
74
|
+
end
|
75
|
+
|
76
|
+
yardoc.docstring.all
|
77
|
+
end
|
78
|
+
|
79
|
+
# @param method [String]
|
80
|
+
# @return [YARD::CodeObjects::MethodObject, nil]
|
81
|
+
def rspec_yardoc_tags_at(method_path)
|
82
|
+
self.class.rspec_yardoc_tags.find { |tag| tag.path == method_path }
|
83
|
+
end
|
84
|
+
|
61
85
|
# @return [Array<String>]
|
62
86
|
def rspec_context_block_methods
|
63
87
|
config.let_methods + Rspec::HOOK_METHODS + Rspec::EXAMPLE_METHODS
|
64
88
|
end
|
89
|
+
|
90
|
+
# @return [Solargraph::Rspec::Config]
|
91
|
+
def config
|
92
|
+
Solargraph::Rspec::Convention.config
|
93
|
+
end
|
65
94
|
end
|
66
95
|
end
|
67
96
|
end
|
@@ -1,58 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
3
|
+
require_relative 'base'
|
4
4
|
|
5
5
|
module Solargraph
|
6
6
|
module Rspec
|
7
7
|
module Correctors
|
8
|
-
#
|
9
|
-
#
|
10
|
-
class ExampleAndHookBlocksBindingCorrector <
|
8
|
+
# RSpec executes example and hook blocks in the context of the example group (ie. describe blocks).
|
9
|
+
# This correctors sets the right bindings to those blocks.
|
10
|
+
class ExampleAndHookBlocksBindingCorrector < Base
|
11
11
|
# @param source_map [Solargraph::SourceMap]
|
12
12
|
# @return [void]
|
13
13
|
def correct(source_map)
|
14
|
-
rspec_walker.on_example_block do |
|
15
|
-
bind_closest_namespace(
|
16
|
-
|
17
|
-
yield [] if block_given?
|
14
|
+
rspec_walker.on_example_block do |location_range|
|
15
|
+
bind_closest_namespace(location_range, source_map)
|
18
16
|
end
|
19
17
|
|
20
|
-
rspec_walker.on_hook_block do |
|
21
|
-
bind_closest_namespace(
|
22
|
-
|
23
|
-
yield [] if block_given?
|
18
|
+
rspec_walker.on_hook_block do |location_range|
|
19
|
+
bind_closest_namespace(location_range, source_map)
|
24
20
|
end
|
25
21
|
|
26
|
-
rspec_walker.on_let_method do |
|
27
|
-
bind_closest_namespace(
|
28
|
-
|
29
|
-
yield [] if block_given?
|
22
|
+
rspec_walker.on_let_method do |_method_name, location_range|
|
23
|
+
bind_closest_namespace(location_range, source_map)
|
30
24
|
end
|
31
25
|
|
32
|
-
rspec_walker.on_blocks_in_examples do |
|
33
|
-
bind_closest_namespace(
|
34
|
-
|
35
|
-
yield [] if block_given?
|
26
|
+
rspec_walker.on_blocks_in_examples do |location_range|
|
27
|
+
bind_closest_namespace(location_range, source_map)
|
36
28
|
end
|
37
29
|
|
38
|
-
rspec_walker.on_subject do |
|
39
|
-
bind_closest_namespace(
|
40
|
-
|
41
|
-
yield [] if block_given?
|
30
|
+
rspec_walker.on_subject do |_method_name, location_range|
|
31
|
+
bind_closest_namespace(location_range, source_map)
|
42
32
|
end
|
43
33
|
end
|
44
34
|
|
45
35
|
private
|
46
36
|
|
47
|
-
# @param
|
37
|
+
# @param location_range [Solargraph::Range]
|
48
38
|
# @param source_map [Solargraph::SourceMap]
|
49
39
|
# @return [void]
|
50
|
-
def bind_closest_namespace(
|
51
|
-
namespace_pin = closest_namespace_pin(namespace_pins,
|
40
|
+
def bind_closest_namespace(location_range, source_map)
|
41
|
+
namespace_pin = closest_namespace_pin(namespace_pins, location_range.start.line)
|
52
42
|
return unless namespace_pin
|
53
43
|
|
54
|
-
original_block_pin = source_map.locate_block_pin(
|
55
|
-
|
44
|
+
original_block_pin = source_map.locate_block_pin(location_range.start.line,
|
45
|
+
location_range.start.column)
|
56
46
|
original_block_pin_index = source_map.pins.index(original_block_pin)
|
57
47
|
fixed_namespace_block_pin = Solargraph::Pin::Block.new(
|
58
48
|
closure: example_run_method(namespace_pin),
|
@@ -67,7 +57,7 @@ module Solargraph
|
|
67
57
|
# @param namespace_pin [Solargraph::Pin::Namespace]
|
68
58
|
# @return [Solargraph::Pin::Method]
|
69
59
|
def example_run_method(namespace_pin)
|
70
|
-
|
60
|
+
PinFactory.build_public_method(
|
71
61
|
namespace_pin,
|
72
62
|
'run',
|
73
63
|
# https://github.com/rspec/rspec-core/blob/main/lib/rspec/core/example.rb#L246
|
@@ -1,40 +1,38 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
3
|
+
require_relative 'base'
|
4
4
|
|
5
5
|
module Solargraph
|
6
6
|
module Rspec
|
7
7
|
module Correctors
|
8
8
|
# Defines let-like methods in the example group block
|
9
|
-
class LetMethodsCorrector <
|
9
|
+
class LetMethodsCorrector < Base
|
10
10
|
# @param source_map [Solargraph::SourceMap]
|
11
11
|
# @return [void]
|
12
12
|
def correct(_source_map)
|
13
|
-
rspec_walker.on_let_method do |
|
14
|
-
namespace_pin = closest_namespace_pin(namespace_pins,
|
13
|
+
rspec_walker.on_let_method do |let_name, location_range, fake_method_ast|
|
14
|
+
namespace_pin = closest_namespace_pin(namespace_pins, location_range.start.line)
|
15
15
|
next unless namespace_pin
|
16
16
|
|
17
|
-
pin = rspec_let_method(namespace_pin,
|
18
|
-
|
17
|
+
pin = rspec_let_method(namespace_pin, let_name, location_range, fake_method_ast)
|
18
|
+
add_pin(pin)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
private
|
23
23
|
|
24
24
|
# @param namespace [Pin::Namespace]
|
25
|
-
# @param
|
25
|
+
# @param method_name [String]
|
26
|
+
# @param node [RubyVM::AbstractSyntaxTree::Node]
|
26
27
|
# @param types [Array<String>, nil]
|
27
28
|
# @return [Pin::Method, nil]
|
28
|
-
def rspec_let_method(namespace,
|
29
|
-
|
30
|
-
return unless ast.children[2]&.children
|
31
|
-
|
32
|
-
method_name = ast.children[2].children[0]&.to_s or return
|
33
|
-
Util.build_public_method(
|
29
|
+
def rspec_let_method(namespace, method_name, location_range, node = nil, types: nil)
|
30
|
+
PinFactory.build_public_method(
|
34
31
|
namespace,
|
35
32
|
method_name,
|
33
|
+
node: node,
|
36
34
|
types: types,
|
37
|
-
location:
|
35
|
+
location: PinFactory.build_location(location_range, namespace.filename),
|
38
36
|
scope: :instance
|
39
37
|
)
|
40
38
|
end
|