diff options
Diffstat (limited to 'spec/syntax_suggest/unit')
| -rw-r--r-- | spec/syntax_suggest/unit/api_spec.rb | 10 | ||||
| -rw-r--r-- | spec/syntax_suggest/unit/clean_document_spec.rb | 2 | ||||
| -rw-r--r-- | spec/syntax_suggest/unit/code_block_spec.rb | 2 | ||||
| -rw-r--r-- | spec/syntax_suggest/unit/code_line_spec.rb | 15 | ||||
| -rw-r--r-- | spec/syntax_suggest/unit/core_ext_spec.rb | 2 | ||||
| -rw-r--r-- | spec/syntax_suggest/unit/explain_syntax_spec.rb | 32 | ||||
| -rw-r--r-- | spec/syntax_suggest/unit/lex_all_spec.rb | 26 | ||||
| -rw-r--r-- | spec/syntax_suggest/unit/mini_stringio_spec.rb | 25 | ||||
| -rw-r--r-- | spec/syntax_suggest/unit/visitor_spec.rb | 119 |
9 files changed, 183 insertions, 50 deletions
diff --git a/spec/syntax_suggest/unit/api_spec.rb b/spec/syntax_suggest/unit/api_spec.rb index e900b9e10b..9299a17bee 100644 --- a/spec/syntax_suggest/unit/api_spec.rb +++ b/spec/syntax_suggest/unit/api_spec.rb @@ -8,12 +8,6 @@ end module SyntaxSuggest RSpec.describe "Top level SyntaxSuggest api" do - it "doesn't load prism if env var is set" do - skip("SYNTAX_SUGGEST_DISABLE_PRISM not set") unless ENV["SYNTAX_SUGGEST_DISABLE_PRISM"] - - expect(SyntaxSuggest.use_prism_parser?).to be_falsey - end - it "has a `handle_error` interface" do fake_error = Object.new def fake_error.message @@ -69,8 +63,6 @@ module SyntaxSuggest end it "respects highlight API" do - skip if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("3.2") - core_ext_file = lib_dir.join("syntax_suggest").join("core_ext.rb") require_relative core_ext_file @@ -91,8 +83,6 @@ module SyntaxSuggest end it "can be disabled via falsey kwarg" do - skip if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("3.2") - core_ext_file = lib_dir.join("syntax_suggest").join("core_ext.rb") require_relative core_ext_file diff --git a/spec/syntax_suggest/unit/clean_document_spec.rb b/spec/syntax_suggest/unit/clean_document_spec.rb index 5b5ca04cfd..3d83bd13c0 100644 --- a/spec/syntax_suggest/unit/clean_document_spec.rb +++ b/spec/syntax_suggest/unit/clean_document_spec.rb @@ -113,7 +113,7 @@ module SyntaxSuggest lines = CleanDocument.new(source: source).lines expect(lines[0].to_s).to eq($/) expect(lines[1].to_s).to eq('puts "what"' + $/) - expect(lines[2].to_s).to eq($/) + expect(lines[2].to_s).to eq(" " + $/) end it "trailing slash: does not join trailing do" do diff --git a/spec/syntax_suggest/unit/code_block_spec.rb b/spec/syntax_suggest/unit/code_block_spec.rb index 3ab2751b27..dfea307668 100644 --- a/spec/syntax_suggest/unit/code_block_spec.rb +++ b/spec/syntax_suggest/unit/code_block_spec.rb @@ -33,7 +33,7 @@ module SyntaxSuggest array = [block_2, block_1, block_0].sort expect(array.last).to eq(block_2) - block = CodeBlock.new(lines: CodeLine.new(line: " " * 8 + "foo", index: 4, lex: [])) + block = CodeBlock.new(lines: CodeLine.new(line: " " * 8 + "foo", index: 4, tokens: [], consecutive: false)) array.prepend(block) expect(array.max).to eq(block) end diff --git a/spec/syntax_suggest/unit/code_line_spec.rb b/spec/syntax_suggest/unit/code_line_spec.rb index 5b62cc2757..309d3d1c1e 100644 --- a/spec/syntax_suggest/unit/code_line_spec.rb +++ b/spec/syntax_suggest/unit/code_line_spec.rb @@ -17,8 +17,6 @@ module SyntaxSuggest 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 @@ -46,7 +44,7 @@ module SyntaxSuggest 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]) + expect(code_lines.map(&:consecutive?)).to eq([true, true, false, false]) end it "trailing if" do @@ -131,14 +129,15 @@ module SyntaxSuggest it "knows empty lines" do code_lines = CodeLine.from_source(<<~EOM) - # Not empty + # Comment only + foo # Inline comment - # Not empty + bar 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]) + expect(code_lines.map(&:empty?)).to eq([true, false, true, false]) + expect(code_lines.map(&:not_empty?)).to eq([false, true, false, true]) + expect(code_lines.map { |l| SyntaxSuggest.valid?(l) }).to eq([true, true, true, true]) end it "counts indentations" do diff --git a/spec/syntax_suggest/unit/core_ext_spec.rb b/spec/syntax_suggest/unit/core_ext_spec.rb index 499c38a240..d579cc8dc4 100644 --- a/spec/syntax_suggest/unit/core_ext_spec.rb +++ b/spec/syntax_suggest/unit/core_ext_spec.rb @@ -3,8 +3,6 @@ require_relative "../spec_helper" module SyntaxSuggest RSpec.describe "Core extension" do it "SyntaxError monkepatch ensures there is a newline to the end of the file" do - skip if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("3.2") - Dir.mktmpdir do |dir| tmpdir = Pathname(dir) file = tmpdir.join("file.rb") diff --git a/spec/syntax_suggest/unit/explain_syntax_spec.rb b/spec/syntax_suggest/unit/explain_syntax_spec.rb index c62a42b925..7ddb32b8ea 100644 --- a/spec/syntax_suggest/unit/explain_syntax_spec.rb +++ b/spec/syntax_suggest/unit/explain_syntax_spec.rb @@ -17,9 +17,23 @@ module SyntaxSuggest expect(explain.errors.join.strip).to_not be_empty end - it "handles %w[]" do + %w[w W i I].each do |type| + it "handles %#{type}-style array" do + source = <<~EOM + node.is_a?(Op) && %#{type}[| ||].include?(node.value) && + EOM + + explain = ExplainSyntax.new( + code_lines: CodeLine.from_source(source) + ).call + + expect(explain.missing).to eq([]) + end + end + + it "handles %r-style regexp" do source = <<~EOM - node.is_a?(Op) && %w[| ||].include?(node.value) && + node.is_a?(Op) && %r{| ||}.include?(node.value) && EOM explain = ExplainSyntax.new( @@ -29,6 +43,20 @@ module SyntaxSuggest expect(explain.missing).to eq([]) end + ["", "q", "Q"].each do |type| + it "handles %#{type}-style string" do + source = <<~EOM + node.is_a?(Op) && %#{type}(| ||).include?(node.value) && + EOM + + explain = ExplainSyntax.new( + code_lines: CodeLine.from_source(source) + ).call + + expect(explain.missing).to eq([]) + end + end + it "doesn't falsely identify strings or symbols as critical chars" do source = <<~EOM a = ['(', '{', '[', '|'] diff --git a/spec/syntax_suggest/unit/lex_all_spec.rb b/spec/syntax_suggest/unit/lex_all_spec.rb deleted file mode 100644 index 9621c9ecec..0000000000 --- a/spec/syntax_suggest/unit/lex_all_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -require_relative "../spec_helper" - -module SyntaxSuggest - RSpec.describe "EndBlockParse" do - it "finds blocks based on `end` keyword" do - source = <<~EOM - describe "cat" # 1 - Cat.call do # 2 - end # 3 - end # 4 - # 5 - it "dog" do # 6 - Dog.call do # 7 - end # 8 - end # 9 - EOM - - lex = LexAll.new(source: source) - expect(lex.map(&:token).to_s).to include("dog") - expect(lex.first.line).to eq(1) - expect(lex.last.line).to eq(9) - end - end -end diff --git a/spec/syntax_suggest/unit/mini_stringio_spec.rb b/spec/syntax_suggest/unit/mini_stringio_spec.rb new file mode 100644 index 0000000000..75d94deae1 --- /dev/null +++ b/spec/syntax_suggest/unit/mini_stringio_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require_relative "../spec_helper" + +module SyntaxSuggest + RSpec.describe "MiniStringIO" do + it "#puts with no inputs" do + io = MiniStringIO.new + io.puts + expect(io.string).to eq($/) + end + + it "#puts with an input" do + io = MiniStringIO.new + io.puts "Hello" + expect(io.string).to eq(["Hello", $/].join) + end + + it "#puts with an input with a newline" do + io = MiniStringIO.new + io.puts "Hello\n" + expect(io.string).to eq(["Hello\n", $/].join) + end + end +end diff --git a/spec/syntax_suggest/unit/visitor_spec.rb b/spec/syntax_suggest/unit/visitor_spec.rb new file mode 100644 index 0000000000..94eefd1e95 --- /dev/null +++ b/spec/syntax_suggest/unit/visitor_spec.rb @@ -0,0 +1,119 @@ +# frozen_string_literal: true + +require_relative "../spec_helper" + +module SyntaxSuggest + RSpec.describe Visitor do + def visit(source) + ast, _tokens = Prism.parse_lex(source).value + visitor = Visitor.new + visitor.visit(ast) + visitor + end + + describe "#consecutive_lines" do + it "detects dot-leading multi-line chains" do + visitor = visit(<<~RUBY) + User + .where(name: "Earlopain") + .first + RUBY + + expect(visitor.consecutive_lines).to eq(Set[1, 2]) + end + + it "detects dot-trailing multi-line chains" do + visitor = visit(<<~RUBY) + User. + where(name: "Earlopain"). + first + RUBY + + expect(visitor.consecutive_lines).to eq(Set[1, 2]) + end + + it "handles chains separated by comments" do + visitor = visit(<<~RUBY) + User. + # comment + where(name: "Earlopain"). + # another comment + first + RUBY + + # The AST sees through comments — every line except + # the last is consecutive regardless of interleaved comments. + expect(visitor.consecutive_lines).to eq(Set[1, 2, 3, 4]) + end + + it "returns empty for single-line calls" do + visitor = visit(<<~RUBY) + User.where(name: "Earlopain").first + RUBY + + expect(visitor.consecutive_lines).to be_empty + end + + it "returns empty when there is no method chain" do + visitor = visit(<<~RUBY) + puts "hello" + puts "world" + RUBY + + expect(visitor.consecutive_lines).to be_empty + end + + it "handles deeply nested chains" do + visitor = visit(<<~RUBY) + User + .where(name: "Earlopain") + .order(:created_at) + .limit(10) + .first + RUBY + + expect(visitor.consecutive_lines).to eq(Set[1, 2, 3, 4]) + end + end + + describe "#endless_def_keyword_offsets" do + it "records the def location for endless methods" do + visitor = visit(<<~RUBY) + def square(x) = x * x + RUBY + + expect(visitor.endless_def_keyword_offsets).to eq(Set[0]) + end + + it "does not record regular method definitions" do + visitor = visit(<<~RUBY) + def square(x) + x * x + end + RUBY + + expect(visitor.endless_def_keyword_offsets).to be_empty + end + + it "records multiple endless methods" do + visitor = visit(<<~RUBY) + def square(x) = x * x + def double(x) = x * 2 + RUBY + + expect(visitor.endless_def_keyword_offsets).to eq(Set[0, 22]) + end + + it "distinguishes endless from regular in the same source" do + visitor = visit(<<~RUBY) + def square(x) = x * x + def cube(x) + x * x * x + end + RUBY + + expect(visitor.endless_def_keyword_offsets).to eq(Set[0]) + end + end + end +end |
