Skip to content

Commit 1aeeb86

Browse files
authored
Refactor RubyLex and its tests (#427)
* Make sure `RubyLex#set_input`'s context is always present in tests In real-world scenarios, the context should always be non-nil: https://github.com/ruby/irb/blob/master/lib/irb.rb#L489 So we should make sure our test setup reflects that. * Make context a required keyword Since in practice, `set_input`'s context should always be non-nil, its parameters should reflect that. And since `RubyLex#check_state` is only called by `#lex` and `#set_input`, both of which now always require context, we can assume its context should be non-nil too.
1 parent 298b134 commit 1aeeb86

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

lib/irb/ruby-lex.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def self.compile_with_errors_suppressed(code, line_no: 1)
4848
end
4949

5050
# io functions
51-
def set_input(io, p = nil, context: nil, &block)
51+
def set_input(io, p = nil, context:, &block)
5252
@io = io
5353
if @io.respond_to?(:check_termination)
5454
@io.check_termination do |code|
@@ -216,7 +216,7 @@ def check_state(code, tokens = nil, context: nil)
216216
ltype = process_literal_type(tokens)
217217
indent = process_nesting_level(tokens)
218218
continue = process_continue(tokens)
219-
lvars_code = self.class.generate_local_variables_assign_code(context&.local_variables || [])
219+
lvars_code = self.class.generate_local_variables_assign_code(context.local_variables)
220220
code = "#{lvars_code}\n#{code}" if lvars_code
221221
code_block_open = check_code_block(code, tokens)
222222
[ltype, indent, continue, code_block_open]

test/irb/test_ruby_lex.rb

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@ def assert_indenting(lines, correct_space_count, add_new_line)
2424
last_line_index = lines.length - 1
2525
byte_pointer = lines.last.length
2626

27+
context = build_context
28+
context.auto_indent_mode = true
2729
ruby_lex = RubyLex.new()
2830
io = MockIO_AutoIndent.new([lines, last_line_index, byte_pointer, add_new_line]) do |auto_indent|
2931
error_message = "Calculated the wrong number of spaces for:\n #{lines.join("\n")}"
3032
assert_equal(correct_space_count, auto_indent, error_message)
3133
end
32-
ruby_lex.set_input(io)
33-
context = OpenStruct.new(auto_indent_mode: true)
34+
ruby_lex.set_input(io, context: context)
3435
ruby_lex.set_auto_indent(context)
3536
end
3637

@@ -48,11 +49,10 @@ def assert_code_block_open(lines, expected, local_variables: [])
4849

4950
def ruby_lex_for_lines(lines, local_variables: [])
5051
ruby_lex = RubyLex.new()
52+
53+
context = build_context(local_variables)
5154
io = proc{ lines.join("\n") }
52-
ruby_lex.set_input(io, io)
53-
unless local_variables.empty?
54-
context = OpenStruct.new(local_variables: local_variables)
55-
end
55+
ruby_lex.set_input(io, io, context: context)
5656
ruby_lex.lex(context)
5757
ruby_lex
5858
end
@@ -620,7 +620,8 @@ def assert_dynamic_prompt(lines, expected_prompt_list)
620620
ruby_lex.set_prompt do |ltype, indent, continue, line_no|
621621
'%03d:%01d:%1s:%s ' % [line_no, indent, ltype, continue ? '*' : '>']
622622
end
623-
ruby_lex.set_input(io)
623+
context = build_context
624+
ruby_lex.set_input(io, context: context)
624625
end
625626

626627
def test_dyanmic_prompt
@@ -697,5 +698,19 @@ def test_unterminated_heredoc_string_literal
697698
assert_equal('<<A', string_literal&.tok)
698699
end
699700
end
701+
702+
private
703+
704+
def build_context(local_variables = nil)
705+
workspace = IRB::WorkSpace.new
706+
707+
if local_variables
708+
local_variables.each do |n|
709+
workspace.binding.local_variable_set(n, nil)
710+
end
711+
end
712+
713+
IRB::Context.new(nil, workspace)
714+
end
700715
end
701716
end

0 commit comments

Comments
 (0)