Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Increase test coverage #190

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 8, 2022
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
12 changes: 8 additions & 4 deletions lib/syntax_tree/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -497,10 +497,14 @@ def run(argv)
Dir
.glob(pattern)
.each do |filepath|
if File.readable?(filepath) &&
options.ignore_files.none? { File.fnmatch?(_1, filepath) }
queue << FileItem.new(filepath)
end
# Skip past invalid filepaths by default.
next unless File.readable?(filepath)

# Skip past any ignored filepaths.
next if options.ignore_files.any? { File.fnmatch(_1, filepath) }

# Otherwise, a new file item for the given filepath to the list.
queue << FileItem.new(filepath)
end
end

Expand Down
6 changes: 3 additions & 3 deletions lib/syntax_tree/pattern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,11 @@ def compile_binary(node)
def compile_const(node)
value = node.value

if SyntaxTree.const_defined?(value)
if SyntaxTree.const_defined?(value, false)
clazz = SyntaxTree.const_get(value)

->(other) { clazz === other }
elsif Object.const_defined?(value)
elsif Object.const_defined?(value, false)
clazz = Object.const_get(value)

->(other) { clazz === other }
Expand Down Expand Up @@ -179,7 +179,7 @@ def compile_dyna_symbol(node)

->(other) { symbol === other }
else
compile_error(root)
compile_error(node)
end
end

Expand Down
11 changes: 7 additions & 4 deletions lib/syntax_tree/visitor/environment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ module SyntaxTree
# The environment class is used to keep track of local variables and arguments
# inside a particular scope
class Environment
# [Array[Local]] The local variables and arguments defined in this
# environment
attr_reader :locals

# This class tracks the occurrences of a local variable or argument
class Local
# [Symbol] The type of the local (e.g. :argument, :variable)
Expand Down Expand Up @@ -38,6 +34,13 @@ def add_usage(location)
end
end

# [Array[Local]] The local variables and arguments defined in this
# environment
attr_reader :locals

# [Environment | nil] The parent environment
attr_reader :parent

# initialize: (Environment | nil parent) -> void
def initialize(parent = nil)
@locals = {}
Expand Down
8 changes: 0 additions & 8 deletions lib/syntax_tree/visitor/field_visitor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -388,14 +388,6 @@ def visit_excessed_comma(node)
visit_token(node, "excessed_comma")
end

def visit_fcall(node)
node(node, "fcall") do
field("value", node.value)
field("arguments", node.arguments) if node.arguments
comments(node)
end
end

def visit_field(node)
node(node, "field") do
field("parent", node.parent)
Expand Down
66 changes: 64 additions & 2 deletions test/cli_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def test_ast_ignore
def test_ast_syntax_error
result = run_cli("ast", contents: "foo\n<>\nbar\n")
assert_includes(result.stderr, "syntax error")
refute_equal(0, result.status)
end

def test_check
Expand All @@ -51,6 +52,7 @@ def test_check
def test_check_unformatted
result = run_cli("check", contents: "foo")
assert_includes(result.stderr, "expected")
refute_equal(0, result.status)
end

def test_check_print_width
Expand All @@ -59,6 +61,17 @@ def test_check_print_width
assert_includes(result.stdio, "match")
end

def test_check_target_ruby_version
previous = Formatter::OPTIONS[:target_ruby_version]

begin
result = run_cli("check", "--target-ruby-version=2.6.0")
assert_includes(result.stdio, "match")
ensure
Formatter::OPTIONS[:target_ruby_version] = previous
end
end

def test_debug
result = run_cli("debug")
assert_includes(result.stdio, "idempotently")
Expand All @@ -71,6 +84,7 @@ def test_debug_non_idempotent_format
SyntaxTree.stub(:format, formatting) do
result = run_cli("debug")
assert_includes(result.stderr, "idempotently")
refute_equal(0, result.status)
end
end

Expand All @@ -84,6 +98,12 @@ def test_expr
assert_includes(result.stdio, "SyntaxTree::Ident")
end

def test_expr_more_than_one
result = run_cli("expr", contents: "1; 2")
assert_includes(result.stderr, "single expression")
refute_equal(0, result.status)
end

def test_format
result = run_cli("format")
assert_equal("test\n", result.stdio)
Expand All @@ -104,6 +124,17 @@ def test_search
assert_equal(2, result.stdio.lines.length)
end

def test_search_multi_line
result = run_cli("search", "Binary", contents: "1 +\n2")
assert_equal(1, result.stdio.lines.length)
end

def test_search_invalid
result = run_cli("search", "FooBar")
assert_includes(result.stderr, "unable")
refute_equal(0, result.status)
end

def test_version
result = run_cli("version")
assert_includes(result.stdio, SyntaxTree::VERSION.to_s)
Expand All @@ -120,6 +151,29 @@ def test_write
def test_write_syntax_tree
result = run_cli("write", contents: "<>")
assert_includes(result.stderr, "syntax error")
refute_equal(0, result.status)
end

def test_write_script
args = ["write", "-e", "1 + 2"]
stdout, stderr = capture_io { SyntaxTree::CLI.run(args) }

assert_includes stdout, "script"
assert_empty stderr
end

def test_write_stdin
previous = $stdin
$stdin = StringIO.new("1 + 2")

begin
stdout, stderr = capture_io { SyntaxTree::CLI.run(["write"]) }

assert_includes stdout, "stdin"
assert_empty stderr
ensure
$stdin = previous
end
end

def test_help
Expand All @@ -128,8 +182,10 @@ def test_help
end

def test_help_default
*, stderr = capture_io { SyntaxTree::CLI.run(["foobar"]) }
status = 0
*, stderr = capture_io { status = SyntaxTree::CLI.run(["foobar"]) }
assert_includes(stderr, "stree help")
refute_equal(0, status)
end

def test_no_arguments
Expand Down Expand Up @@ -215,6 +271,7 @@ def test_print_width_args_with_config_file_override
result = run_cli("check", "--print-width=82", contents: contents)

assert_includes(result.stderr, "expected")
refute_equal(0, result.status)
end
end

Expand Down Expand Up @@ -251,7 +308,12 @@ def run_cli(command, *args, contents: :default)
status = nil
stdio, stderr =
capture_io do
status = SyntaxTree::CLI.run([command, *args, tempfile.path])
status =
begin
SyntaxTree::CLI.run([command, *args, tempfile.path])
rescue SystemExit => error
error.status
end
end

Result.new(status: status, stdio: stdio, stderr: stderr)
Expand Down
18 changes: 18 additions & 0 deletions test/language_server_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,24 @@ def test_inlay_hint
assert_equal(3, responses.dig(1, :result).size)
end

def test_inlay_hint_invalid
responses = run_server([
Initialize.new(1),
TextDocumentDidOpen.new("file:///path/to/file.rb", "<>"),
TextDocumentInlayHint.new(2, "file:///path/to/file.rb"),
Shutdown.new(3)
])

shape = LanguageServer::Request[[
{ id: 1, result: { capabilities: Hash } },
{ id: 2, result: :any },
{ id: 3, result: {} }
]]

assert_operator(shape, :===, responses)
assert_equal(0, responses.dig(1, :result).size)
end

def test_visualizing
responses = run_server([
Initialize.new(1),
Expand Down
20 changes: 18 additions & 2 deletions test/rake_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,28 @@ module Rake
class CheckTaskTest < Minitest::Test
Invocation = Struct.new(:args)

def test_task_command
assert_raises(NotImplementedError) { Task.new.command }
end

def test_check_task
source_files = "{app,config,lib}/**/*.rb"
CheckTask.new { |t| t.source_files = source_files }

CheckTask.new do |t|
t.source_files = source_files
t.print_width = 100
t.target_ruby_version = Gem::Version.new("2.6.0")
end

expected = [
"check",
"--print-width=100",
"--target-ruby-version=2.6.0",
source_files
]

invocation = invoke("stree:check")
assert_equal(["check", source_files], invocation.args)
assert_equal(expected, invocation.args)
end

def test_write_task
Expand Down
79 changes: 72 additions & 7 deletions test/search_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,50 @@

module SyntaxTree
class SearchTest < Minitest::Test
def test_search_invalid_syntax
assert_raises(Pattern::CompilationError) { search("", "<>") }
end

def test_search_invalid_constant
assert_raises(Pattern::CompilationError) { search("", "Foo") }
end

def test_search_invalid_nested_constant
assert_raises(Pattern::CompilationError) { search("", "Foo::Bar") }
end

def test_search_regexp_with_interpolation
assert_raises(Pattern::CompilationError) { search("", "/\#{foo}/") }
end

def test_search_string_with_interpolation
assert_raises(Pattern::CompilationError) { search("", '"#{foo}"') }
end

def test_search_symbol_with_interpolation
assert_raises(Pattern::CompilationError) { search("", ":\"\#{foo}\"") }
end

def test_search_invalid_node
assert_raises(Pattern::CompilationError) { search("", "Int[^foo]") }
end

def test_search_self
assert_raises(Pattern::CompilationError) { search("", "self") }
end

def test_search_array_pattern_no_constant
results = search("1 + 2", "[Int, Int]")

assert_equal 1, results.length
end

def test_search_array_pattern
results = search("1 + 2", "Binary[Int, Int]")

assert_equal 1, results.length
end

def test_search_binary_or
results = search("Foo + Bar + 1", "VarRef | Int")

Expand All @@ -18,12 +62,24 @@ def test_search_const
assert_equal %w[Bar Baz Foo], results.map { |node| node.value.value }.sort
end

def test_search_object_const
results = search("1 + 2 + 3", "Int[value: String]")

assert_equal 3, results.length
end

def test_search_syntax_tree_const
results = search("Foo + Bar + Baz", "SyntaxTree::VarRef")

assert_equal 3, results.length
end

def test_search_hash_pattern_no_constant
results = search("Foo + Bar + Baz", "{ value: Const }")

assert_equal 3, results.length
end

def test_search_hash_pattern_string
results = search("Foo + Bar + Baz", "VarRef[value: Const[value: 'Foo']]")

Expand All @@ -39,24 +95,33 @@ def test_search_hash_pattern_regexp
end

def test_search_string_empty
results = search("''", "StringLiteral[parts: []]")
results = search("", "''")

assert_equal 1, results.length
assert_empty results
end

def test_search_symbol_empty
results = search(":''", "DynaSymbol[parts: []]")
results = search("", ":''")

assert_empty results
end

def test_search_symbol_plain
results = search("1 + 2", "Binary[operator: :'+']")

assert_equal 1, results.length
end

def test_search_symbol
results = search("1 + 2", "Binary[operator: :+]")

assert_equal 1, results.length
end

private

def search(source, query)
pattern = Pattern.new(query).compile
program = SyntaxTree.parse(source)

Search.new(pattern).scan(program).to_a
SyntaxTree.search(source, query).to_a
end
end
end
Loading