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
16 changes: 16 additions & 0 deletions lib/ruby_language_server/scope_parser_commands/rspec_commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,22 @@ def on_it_command(line, args, rest)
rspec_block_command('it', line, args, rest)
end

def on_let_command(line, args, rest)
# Extract the variable name from the symbol (e.g., :foo -> foo)
# The rest array contains the extracted symbol values from extract_command_rest
var_name = rest.flatten.first
return unless var_name.is_a?(String)

# Extract the column from args structure: [:@ident, "let", [line, column]]
(_, _, (_, column)) = args

# Add the variable to the current scope
add_variable(var_name, line, column)
end

# let! is an eager version of let - alias it using send to avoid syntax issues
send(:alias_method, 'on_let!_command', :on_let_command)

private

def rspec_block_command(prefix, line, _args, rest)
Expand Down
24 changes: 12 additions & 12 deletions spec/lib/ruby_language_server/scope_data/scope_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,16 @@ def baz; end
end
end

# describe '.scopes_at' do
# it 'should find the deepest scope' do
# assert_equal([], root_scope.scopes_at(OpenStruct.new(line: 0)))
# assert_equal([], root_scope.scopes_at(OpenStruct.new(line: 1)))
# assert_equal(foo_scope, root_scope.scopes_at(OpenStruct.new(line: 2)).first)
# assert_equal(bar_class_scope, root_scope.scopes_at(OpenStruct.new(line: 3)).first)
# assert_equal(baz_method_scope, root_scope.scopes_at(OpenStruct.new(line: 6)).first)
# assert_equal(nar_class_scope, root_scope.scopes_at(OpenStruct.new(line: 13)).first)
# assert_equal(naz_method_scope, root_scope.scopes_at(OpenStruct.new(line: 16)).first)
# assert_equal(RubyLanguageServer::ScopeData::Base::TYPE_BLOCK, root_scope.scopes_at(OpenStruct.new(line: 19)).first.class_type)
# end
# end
describe '.scopes_at' do
it 'should find the deepest scope' do
assert_equal([], root_scope.self_and_descendants.for_line(0).where.not(class_type: 'root').to_a)
assert_equal([], root_scope.self_and_descendants.for_line(1).where.not(class_type: 'root').to_a)
assert_equal(foo_scope, root_scope.self_and_descendants.for_line(2).by_path_length.first)
assert_equal(bar_class_scope, root_scope.self_and_descendants.for_line(3).by_path_length.first)
assert_equal(baz_method_scope, root_scope.self_and_descendants.for_line(6).by_path_length.first)
assert_equal(nar_class_scope, root_scope.self_and_descendants.for_line(13).by_path_length.first)
assert_equal(naz_method_scope, root_scope.self_and_descendants.for_line(16).by_path_length.first)
assert_equal(RubyLanguageServer::ScopeData::Base::TYPE_BLOCK, root_scope.self_and_descendants.for_line(19).by_path_length.first.class_type)
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,50 @@
assert_equal('context some context', context_block.name)
end
end

describe 'let variables' do
it 'should capture let variables in the appropriate scope' do
top_describe = @parser.root_scope.children.first
block = top_describe.children.first

# Check that 'foo' variable is in the top describe block
foo_variable = block.variables.find { |v| v.name == 'foo' }
refute_nil(foo_variable, 'Expected to find foo variable in top describe block')
assert_equal(2, foo_variable.line)
end

it 'should capture let variables in nested scopes' do
top_describe = @parser.root_scope.children.first
block = top_describe.children.first
some_thing_describe = block.children.find { |c| c.name == 'describe some thing' }
some_thing_block = some_thing_describe.children.first

# Check that 'common' variable is in the nested describe block
common_variable = some_thing_block.variables.find { |v| v.name == 'common' }
refute_nil(common_variable, 'Expected to find common variable in nested describe block')
assert_equal(5, common_variable.line)
end
end

describe 'let! variables' do
before do
@let_bang_code = <<-SOURCE
describe 'eager evaluation' do
let!(:eager_var) { 'eager_value' }
end
SOURCE
@let_bang_parser = RubyLanguageServer::ScopeParser.new(@let_bang_code)
end

it 'should capture let! variables' do
# Get the describe scope for 'eager evaluation', not the first one which is from another test
describe_scope = @let_bang_parser.root_scope.children.find { |c| c.name.include?('eager evaluation') }
block = describe_scope.children.first

# Check that 'eager_var' variable is captured
eager_variable = block.variables.find { |v| v.name == 'eager_var' }
refute_nil(eager_variable, 'Expected to find eager_var from let!')
assert_equal(2, eager_variable.line)
end
end
end