mirror of
https://github.com/ruby/ruby.git
synced 2025-08-24 05:25:34 +02:00

When removing comments I previously replaced them with a newline. This loses some context and may affect the order of the indent search which in turn affects the final result. By preserving whitespace in front of the comment, we preserve the "natural" indentation order of the line while also allowing the parser/lexer to see and join naturally consecutive (method chain) lines. close https://github.com/ruby/syntax_suggest/pull/177
165 lines
4.1 KiB
Ruby
165 lines
4.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require_relative "../spec_helper"
|
|
|
|
module SyntaxSuggest
|
|
RSpec.describe CodeLine do
|
|
it "bug in keyword detection" do
|
|
lines = CodeLine.from_source(<<~'EOM')
|
|
def to_json(*opts)
|
|
{
|
|
type: :module,
|
|
}.to_json(*opts)
|
|
end
|
|
EOM
|
|
expect(lines.count(&:is_kw?)).to eq(1)
|
|
expect(lines.count(&:is_end?)).to eq(1)
|
|
end
|
|
|
|
it "supports endless method definitions" do
|
|
skip("Unsupported ruby version") unless Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3")
|
|
|
|
line = CodeLine.from_source(<<~'EOM').first
|
|
def square(x) = x * x
|
|
EOM
|
|
|
|
expect(line.is_kw?).to be_falsey
|
|
expect(line.is_end?).to be_falsey
|
|
end
|
|
|
|
it "retains original line value, after being marked invisible" do
|
|
line = CodeLine.from_source(<<~'EOM').first
|
|
puts "lol"
|
|
EOM
|
|
expect(line.line).to match('puts "lol"')
|
|
line.mark_invisible
|
|
expect(line.line).to eq("")
|
|
expect(line.original).to match('puts "lol"')
|
|
end
|
|
|
|
it "knows which lines can be joined" do
|
|
code_lines = CodeLine.from_source(<<~'EOM')
|
|
user = User.
|
|
where(name: 'schneems').
|
|
first
|
|
puts user.name
|
|
EOM
|
|
|
|
# Indicates line 1 can join 2, 2 can join 3, but 3 won't join it's next line
|
|
expect(code_lines.map(&:ignore_newline_not_beg?)).to eq([true, true, false, false])
|
|
end
|
|
|
|
it "trailing if" do
|
|
code_lines = CodeLine.from_source(<<~'EOM')
|
|
puts "lol" if foo
|
|
if foo
|
|
end
|
|
EOM
|
|
|
|
expect(code_lines.map(&:is_kw?)).to eq([false, true, false])
|
|
end
|
|
|
|
it "trailing unless" do
|
|
code_lines = CodeLine.from_source(<<~'EOM')
|
|
puts "lol" unless foo
|
|
unless foo
|
|
end
|
|
EOM
|
|
|
|
expect(code_lines.map(&:is_kw?)).to eq([false, true, false])
|
|
end
|
|
|
|
it "trailing slash" do
|
|
code_lines = CodeLine.from_source(<<~'EOM')
|
|
it "trailing s" \
|
|
"lash" do
|
|
EOM
|
|
|
|
expect(code_lines.map(&:trailing_slash?)).to eq([true, false])
|
|
|
|
code_lines = CodeLine.from_source(<<~'EOM')
|
|
amazing_print: ->(obj) { obj.ai + "\n" },
|
|
EOM
|
|
expect(code_lines.map(&:trailing_slash?)).to eq([false])
|
|
end
|
|
|
|
it "knows it's got an end" do
|
|
line = CodeLine.from_source(" end").first
|
|
|
|
expect(line.is_end?).to be_truthy
|
|
expect(line.is_kw?).to be_falsey
|
|
end
|
|
|
|
it "knows it's got a keyword" do
|
|
line = CodeLine.from_source(" if").first
|
|
|
|
expect(line.is_end?).to be_falsey
|
|
expect(line.is_kw?).to be_truthy
|
|
end
|
|
|
|
it "ignores marked lines" do
|
|
code_lines = CodeLine.from_source(<<~EOM)
|
|
def foo
|
|
Array(value) |x|
|
|
end
|
|
end
|
|
EOM
|
|
|
|
expect(SyntaxSuggest.valid?(code_lines)).to be_falsey
|
|
expect(code_lines.join).to eq(<<~EOM)
|
|
def foo
|
|
Array(value) |x|
|
|
end
|
|
end
|
|
EOM
|
|
|
|
expect(code_lines[0].visible?).to be_truthy
|
|
expect(code_lines[3].visible?).to be_truthy
|
|
|
|
code_lines[0].mark_invisible
|
|
code_lines[3].mark_invisible
|
|
|
|
expect(code_lines[0].visible?).to be_falsey
|
|
expect(code_lines[3].visible?).to be_falsey
|
|
|
|
expect(code_lines.join).to eq(<<~EOM.indent(2))
|
|
Array(value) |x|
|
|
end
|
|
EOM
|
|
expect(SyntaxSuggest.valid?(code_lines)).to be_falsey
|
|
end
|
|
|
|
it "knows empty lines" do
|
|
code_lines = CodeLine.from_source(<<~EOM)
|
|
# Not empty
|
|
|
|
# Not empty
|
|
EOM
|
|
|
|
expect(code_lines.map(&:empty?)).to eq([false, true, false])
|
|
expect(code_lines.map(&:not_empty?)).to eq([true, false, true])
|
|
expect(code_lines.map { |l| SyntaxSuggest.valid?(l) }).to eq([true, true, true])
|
|
end
|
|
|
|
it "counts indentations" do
|
|
code_lines = CodeLine.from_source(<<~EOM)
|
|
def foo
|
|
Array(value) |x|
|
|
puts 'lol'
|
|
end
|
|
end
|
|
EOM
|
|
|
|
expect(code_lines.map(&:indent)).to eq([0, 2, 4, 2, 0])
|
|
end
|
|
|
|
it "doesn't count empty lines as having an indentation" do
|
|
code_lines = CodeLine.from_source(<<~EOM)
|
|
|
|
|
|
EOM
|
|
|
|
expect(code_lines.map(&:indent)).to eq([0, 0])
|
|
end
|
|
end
|
|
end
|