Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@

# rspec failure tracking
.rspec_status

vendor
.solargraph.yml
2 changes: 0 additions & 2 deletions lib/solargraph/rspec/convention.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
require_relative 'correctors/described_class_corrector'
require_relative 'correctors/let_methods_corrector'
require_relative 'correctors/subject_method_corrector'
require_relative 'correctors/context_block_methods_corrector'
require_relative 'correctors/dsl_methods_corrector'
require_relative 'test_helpers'
require_relative 'pin_factory'
Expand Down Expand Up @@ -52,7 +51,6 @@ module Rspec

# @type [Array<Class<Correctors::Base>>]
CORRECTOR_CLASSES = [
Correctors::ContextBlockMethodsCorrector,
Correctors::ContextBlockNamespaceCorrector,
Correctors::DescribedClassCorrector,
Correctors::DslMethodsCorrector,
Expand Down
10 changes: 10 additions & 0 deletions lib/solargraph/rspec/correctors/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ def closest_namespace_pin(namespace_pins, line)
distance >= 0 ? distance : Float::INFINITY
end
end

# Overrides a pin's closure, and resets all the needed instance vars
# @param pin [Solargraph::Pin::Base]
# @param new_closure [Solargraph::Pin::Closure]
def override_closure(pin, new_closure)
pin.instance_variable_set('@closure', new_closure)
pin.reset_generated!

pin.remove_instance_variable(:@path) if pin.instance_variables.include? :@path
end
end
end
end
Expand Down
36 changes: 0 additions & 36 deletions lib/solargraph/rspec/correctors/context_block_methods_corrector.rb

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ def correct(source_map)
# @param location_range [Solargraph::Range]
rspec_walker.on_each_context_block do |namespace_name, location_range|
original_block_pin = source_map.locate_block_pin(location_range.start.line, location_range.start.column)
original_block_pin_index = source_map.pins.index(original_block_pin)
location = PinFactory.build_location(location_range, source_map.filename)

# Define a dynamic module for the example group block
Expand All @@ -26,17 +25,10 @@ def correct(source_map)
location: location
)

fixed_namespace_block_pin = Solargraph::Pin::Block.new(
closure: namespace_pin,
location: original_block_pin.location,
receiver: original_block_pin.receiver,
scope: original_block_pin.scope
)

source_map.pins[original_block_pin_index] = fixed_namespace_block_pin
override_closure(original_block_pin, namespace_pin)

# Include DSL methods in the example group block
# TOOD: This does not work on solagraph! Class methods are not included from parent class.
# TODO: This does not work on solagraph! Class methods are not included from parent class.
namespace_extend_pin = PinFactory.build_module_extend(
namespace_pin,
root_example_group_namespace_pin.name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,8 @@ def bind_closest_namespace(location_range, source_map)

original_block_pin = source_map.locate_block_pin(location_range.start.line,
location_range.start.column)
original_block_pin_index = source_map.pins.index(original_block_pin)
fixed_namespace_block_pin = Solargraph::Pin::Block.new(
closure: example_run_method(namespace_pin),
location: original_block_pin.location,
receiver: original_block_pin.receiver,
scope: original_block_pin.scope
)

source_map.pins[original_block_pin_index] = fixed_namespace_block_pin
override_closure(original_block_pin, example_run_method(namespace_pin))
end

# @param namespace_pin [Solargraph::Pin::Namespace]
Expand Down
82 changes: 81 additions & 1 deletion spec/solargraph/rspec/convention_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,8 @@ def load_and_assert_type(let_declaration, let_name, expected_type)
end

it 'infers type for some_object' do
load_and_assert_type(<<~RUBY, 'some_object', 'MyClass')
pending('https://github.com/castwide/solargraph/pull/1008')
load_and_assert_type(<<~RUBY, 'some_object', 'RSpec::ExampleGroups::TestSomeNamespaceTransaction::MyClass')
class MyClass; end
let(:some_object) { MyClass.new }
RUBY
Expand Down Expand Up @@ -598,6 +599,85 @@ class MyClass; end
'Class'
)
end

describe 'on variables' do
it 'should parse result of a method defined in an example' do
load_string filename, <<~RUBY
RSpec.describe SomeNamespace::Transaction, type: :model do
it 'some example' do
# @return [Numeric]
def example_method
end

result = example_method
end
end
RUBY

var_pin = expect_local_variable_type('result', 'Numeric')
# This is mostly important of includes outside an include pin (ie. https://github.com/lekemula/solargraph-rspec/pull/13)
expect(var_pin.namespace).to eql('RSpec::ExampleGroups::TestSomeNamespaceTransaction')
end

it 'should parse result of a method defined in a context' do
load_string filename, <<~RUBY
RSpec.describe SomeNamespace::Transaction, type: :model do
# @return [String]
def example_method
end

it 'some example' do
result = example_method
end
end
RUBY

var_pin = expect_local_variable_type('result', 'String')
expect(var_pin.namespace).to eql('RSpec::ExampleGroups::TestSomeNamespaceTransaction')
end

it 'should parse result of a module method included in an example' do
load_string filename, <<~RUBY
module SomeModule
# @return [String]
def example_method
end
end

RSpec.describe SomeNamespace::Transaction, type: :model do
it 'some example' do
include SomeModule

result = example_method
end
end
RUBY

var_pin = expect_local_variable_type('result', 'String')
expect(var_pin.namespace).to eql('RSpec::ExampleGroups::TestSomeNamespaceTransaction')
end

it 'should parse result of a module method included in a context' do
load_string filename, <<~RUBY
module SomeModule
# @return [Numeric]
def example_method
end
end

RSpec.describe SomeNamespace::Transaction, type: :model do
include SomeModule

it 'some example' do
result = example_method
end
end
RUBY

var_pin = expect_local_variable_type('result', 'Numeric')
expect(var_pin.namespace).to eql('RSpec::ExampleGroups::TestSomeNamespaceTransaction')
end
end
end

describe 'configurations' do
Expand Down
18 changes: 18 additions & 0 deletions spec/support/solargraph_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ def find_pins(path, map = api_map)
map.pins.select { |p| p.path == path }
end

# @return [Array<Solargraph::Pin::Base>]
def completion_pins_at(filename, position, map = api_map)
# @type [Solargraph::SourceMap::Clip]
clip = map.clip_at(filename, position)
cursor = clip.send(:cursor)
word = cursor.chain.links.first.word
Expand All @@ -74,4 +76,20 @@ def completion_pins_at(filename, position, map = api_map)
def completion_at(filename, position, map = api_map)
completion_pins_at(filename, position, map).map(&:name)
end

# Expect that a local can be inferred with +expected_type+
#
# @param var_name [String]
# @param expected_type [String]
# @param file [String] The filename (defaults to filename defined in test)
# @param map [Solargraph::ApiMap] The Api Map (defaults to the one defined in a test)
#
# @return [Solargraph::Pin::BaseVariable] The variable pin
def expect_local_variable_type(var_name, expected_type, file = filename, map = api_map)
var_pin = map.source_map(file).locals.find { |p| p.name == var_name }
expect(var_pin).not_to be_nil
expect(var_pin.probe(map).to_s).to eql(expected_type)

var_pin
end
end