1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/spec/syntax_suggest/unit/code_search_spec.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

506 lines
12 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
require_relative "../spec_helper"
module SyntaxSuggest
RSpec.describe CodeSearch do
it "rexe regression" do
lines = fixtures_dir.join("rexe.rb.txt").read.lines
lines.delete_at(148 - 1)
source = lines.join
search = CodeSearch.new(source)
search.call
expect(search.invalid_blocks.join.strip).to eq(<<~'EOM'.strip)
class Lookups
EOM
end
it "squished do regression" do
source = <<~'EOM'
def call
trydo
@options = CommandLineParser.new.parse
options.requires.each { |r| require!(r) }
load_global_config_if_exists
options.loads.each { |file| load(file) }
@user_source_code = ARGV.join(' ')
@user_source_code = 'self' if @user_source_code == ''
@callable = create_callable
init_rexe_context
init_parser_and_formatters
# This is where the user's source code will be executed; the action will in turn call `execute`.
lookup_action(options.input_mode).call unless options.noop
output_log_entry
end # one
end # two
EOM
search = CodeSearch.new(source)
search.call
expect(search.invalid_blocks.join).to eq(<<~'EOM'.indent(2))
trydo
end # one
EOM
end
it "regression test ambiguous end" do
source = <<~'EOM'
def call # 0
print "lol" # 1
end # one # 2
end # two # 3
EOM
search = CodeSearch.new(source)
search.call
expect(search.invalid_blocks.join).to eq(<<~'EOM')
end # two # 3
EOM
end
it "regression dog test" do
source = <<~'EOM'
class Dog
def bark
puts "woof"
end
EOM
search = CodeSearch.new(source)
search.call
expect(search.invalid_blocks.join).to eq(<<~'EOM')
class Dog
EOM
expect(search.invalid_blocks.first.lines.length).to eq(4)
end
it "handles mismatched |" do
source = <<~EOM
class Blerg
Foo.call do |a
end # one
puts lol
class Foo
end # two
end # three
EOM
search = CodeSearch.new(source)
search.call
expect(search.invalid_blocks.join).to eq(<<~'EOM'.indent(2))
Foo.call do |a
end # one
EOM
end
it "handles mismatched }" do
source = <<~EOM
class Blerg
Foo.call do {
puts lol
class Foo
end # two
end # three
EOM
search = CodeSearch.new(source)
search.call
expect(search.invalid_blocks.join).to eq(<<~'EOM'.indent(2))
Foo.call do {
EOM
end
it "handles no spaces between blocks and trailing slash" do
source = <<~'EOM'
require "rails_helper"
RSpec.describe Foo, type: :model do
describe "#bar" do
context "context" do
it "foos the bar with a foo and then bazes the foo with a bar to"\
"fooify the barred bar" do
travel_to DateTime.new(2020, 10, 1, 10, 0, 0) do
foo = build(:foo)
end
end
end
end
describe "#baz?" do
context "baz has barred the foo" do
it "returns true" do # <== HERE
end
end
end
EOM
search = CodeSearch.new(source)
search.call
expect(search.invalid_blocks.join.strip).to eq('it "returns true" do # <== HERE')
end
it "handles no spaces between blocks" do
source = <<~'EOM'
context "foo bar" do
it "bars the foo" do
travel_to DateTime.new(2020, 10, 1, 10, 0, 0) do
end
end
end
context "test" do
it "should" do
end
EOM
search = CodeSearch.new(source)
search.call
expect(search.invalid_blocks.join.strip).to eq('it "should" do')
end
it "records debugging steps to a directory" do
Dir.mktmpdir do |dir|
dir = Pathname(dir)
search = CodeSearch.new(<<~'EOM', record_dir: dir)
class OH
def hello
def hai
end
end
EOM
search.call
expect(search.record_dir.entries.map(&:to_s)).to include("1-add-1-(3__4).txt")
expect(search.record_dir.join("1-add-1-(3__4).txt").read).to include(<<~EOM)
1 class OH
2 def hello
3 def hai
4 end
5 end
EOM
end
end
it "def with missing end" do
search = CodeSearch.new(<<~'EOM')
class OH
def hello
def hai
puts "lol"
end
end
EOM
search.call
expect(search.invalid_blocks.join.strip).to eq("def hello")
search = CodeSearch.new(<<~'EOM')
class OH
def hello
def hai
end
end
EOM
search.call
expect(search.invalid_blocks.join.strip).to eq("def hello")
search = CodeSearch.new(<<~'EOM')
class OH
def hello
def hai
end
end
EOM
search.call
expect(search.invalid_blocks.join).to eq(<<~'EOM'.indent(2))
def hello
EOM
end
describe "real world cases" do
it "finds hanging def in this project" do
source_string = fixtures_dir.join("this_project_extra_def.rb.txt").read
search = CodeSearch.new(source_string)
search.call
document = DisplayCodeWithLineNumbers.new(
lines: search.code_lines.select(&:visible?),
terminal: false,
highlight_lines: search.invalid_blocks.flat_map(&:lines)
).call
expect(document).to include(<<~'EOM')
36 def filename
EOM
end
it "Format Code blocks real world example" do
search = CodeSearch.new(<<~'EOM')
require 'rails_helper'
RSpec.describe AclassNameHere, type: :worker do
describe "thing" do
context "when" do
let(:thing) { stuff }
let(:another_thing) { moarstuff }
subject { foo.new.perform(foo.id, true) }
it "stuff" do
subject
expect(foo.foo.foo).to eq(true)
end
end
end # line 16 accidental end, but valid block
context "stuff" do
let(:thing) { create(:foo, foo: stuff) }
let(:another_thing) { create(:stuff) }
subject { described_class.new.perform(foo.id, false) }
it "more stuff" do
subject
expect(foo.foo.foo).to eq(false)
end
end
end # mismatched due to 16
end
EOM
search.call
document = DisplayCodeWithLineNumbers.new(
lines: search.code_lines.select(&:visible?),
terminal: false,
highlight_lines: search.invalid_blocks.flat_map(&:lines)
).call
expect(document).to include(<<~'EOM')
1 require 'rails_helper'
2
3 RSpec.describe AclassNameHere, type: :worker do
4 describe "thing" do
16 end # line 16 accidental end, but valid block
30 end # mismatched due to 16
31 end
EOM
end
end
# For code that's not perfectly formatted, we ideally want to do our best
# These examples represent the results that exist today, but I would like to improve upon them
describe "needs improvement" do
describe "mis-matched-indentation" do
it "extra space before end" do
search = CodeSearch.new(<<~'EOM')
Foo.call
def foo
puts "lol"
puts "lol"
end # one
end # two
EOM
search.call
expect(search.invalid_blocks.join).to eq(<<~'EOM')
Foo.call
end # two
EOM
end
it "stacked ends 2" do
search = CodeSearch.new(<<~'EOM')
def cat
blerg
end
Foo.call do
end # one
end # two
def dog
end
EOM
search.call
expect(search.invalid_blocks.join).to eq(<<~'EOM')
Foo.call do
end # one
end # two
EOM
end
it "stacked ends " do
search = CodeSearch.new(<<~'EOM')
Foo.call
def foo
puts "lol"
puts "lol"
end
end
EOM
search.call
expect(search.invalid_blocks.join).to eq(<<~'EOM')
Foo.call
end
EOM
end
it "missing space before end" do
search = CodeSearch.new(<<~'EOM')
Foo.call
def foo
puts "lol"
puts "lol"
end
end
EOM
search.call
# expand-1 and expand-2 seem to be broken?
expect(search.invalid_blocks.join).to eq(<<~'EOM')
Foo.call
end
EOM
end
end
end
it "returns syntax error in outer block without inner block" do
search = CodeSearch.new(<<~'EOM')
Foo.call
def foo
puts "lol"
puts "lol"
end # one
end # two
EOM
search.call
expect(search.invalid_blocks.join).to eq(<<~'EOM')
Foo.call
end # two
EOM
end
it "doesn't just return an empty `end`" do
search = CodeSearch.new(<<~'EOM')
Foo.call
end
EOM
search.call
expect(search.invalid_blocks.join).to eq(<<~'EOM')
Foo.call
end
EOM
end
it "finds multiple syntax errors" do
search = CodeSearch.new(<<~'EOM')
describe "hi" do
Foo.call
end
end
it "blerg" do
Bar.call
end
end
EOM
search.call
expect(search.invalid_blocks.join).to eq(<<~'EOM'.indent(2))
Foo.call
end
Bar.call
end
EOM
end
it "finds a typo def" do
search = CodeSearch.new(<<~'EOM')
defzfoo
puts "lol"
end
EOM
search.call
expect(search.invalid_blocks.join).to eq(<<~'EOM')
defzfoo
end
EOM
end
it "finds a mis-matched def" do
search = CodeSearch.new(<<~'EOM')
def foo
def blerg
end
EOM
search.call
expect(search.invalid_blocks.join).to eq(<<~'EOM'.indent(2))
def blerg
EOM
end
it "finds a naked end" do
search = CodeSearch.new(<<~'EOM')
def foo
end # one
end # two
EOM
search.call
expect(search.invalid_blocks.join).to eq(<<~'EOM'.indent(2))
end # one
EOM
end
it "returns when no invalid blocks are found" do
search = CodeSearch.new(<<~'EOM')
def foo
puts 'lol'
end
EOM
search.call
expect(search.invalid_blocks).to eq([])
end
it "expands frontier by eliminating valid lines" do
search = CodeSearch.new(<<~'EOM')
def foo
puts 'lol'
end
EOM
search.create_blocks_from_untracked_lines
expect(search.code_lines.join).to eq(<<~'EOM')
def foo
end
EOM
end
end
end