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

Commit fa63c3f

Browse files
authored
Merge pull request #92 from ruby-syntax-tree/tests
Tests
2 parents 828f7cb + b22cb5f commit fa63c3f

28 files changed

+673
-217
lines changed

.rubocop.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,6 @@ Style/PerlBackrefs:
7878

7979
Style/SpecialGlobalVars:
8080
Enabled: false
81+
82+
Style/StructInheritance:
83+
Enabled: false

lib/syntax_tree/formatter.rb

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@ module SyntaxTree
44
# A slightly enhanced PP that knows how to format recursively including
55
# comments.
66
class Formatter < PrettierPrint
7+
# We want to minimize as much as possible the number of options that are
8+
# available in syntax tree. For the most part, if users want non-default
9+
# formatting, they should override the format methods on the specific nodes
10+
# themselves. However, because of some history with prettier and the fact
11+
# that folks have become entrenched in their ways, we decided to provide a
12+
# small amount of configurability.
13+
#
14+
# Note that we're keeping this in a global-ish hash instead of just
15+
# overriding methods on classes so that other plugins can reference this if
16+
# necessary. For example, the RBS plugin references the quote style.
17+
OPTIONS = { quote: "\"", trailing_comma: false }
18+
719
COMMENT_PRIORITY = 1
820
HEREDOC_PRIORITY = 2
921

@@ -14,13 +26,20 @@ class Formatter < PrettierPrint
1426
attr_reader :quote, :trailing_comma
1527
alias trailing_comma? trailing_comma
1628

17-
def initialize(source, ...)
18-
super(...)
29+
def initialize(
30+
source,
31+
*args,
32+
quote: OPTIONS[:quote],
33+
trailing_comma: OPTIONS[:trailing_comma]
34+
)
35+
super(*args)
1936

2037
@source = source
2138
@stack = []
22-
@quote = "\""
23-
@trailing_comma = false
39+
40+
# Memoizing these values per formatter to make access faster.
41+
@quote = quote
42+
@trailing_comma = trailing_comma
2443
end
2544

2645
def self.format(source, node)

lib/syntax_tree/formatter/single_quotes.rb

Lines changed: 0 additions & 13 deletions
This file was deleted.

lib/syntax_tree/formatter/trailing_comma.rb

Lines changed: 0 additions & 13 deletions
This file was deleted.

lib/syntax_tree/language_server.rb

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,11 @@ def run
7070
id:,
7171
params: { textDocument: { uri: } }
7272
}
73-
output = []
74-
PP.pp(SyntaxTree.parse(store[uri]), output)
75-
write(id: id, result: output.join)
73+
write(id: id, result: PP.pp(SyntaxTree.parse(store[uri]), +""))
7674
in method: %r{\$/.+}
7775
# ignored
7876
else
79-
raise "Unhandled: #{request}"
77+
raise ArgumentError, "Unhandled: #{request}"
8078
end
8179
end
8280
end
@@ -109,10 +107,6 @@ def format(source)
109107
}
110108
end
111109

112-
def log(message)
113-
write(method: "window/logMessage", params: { type: 4, message: message })
114-
end
115-
116110
def inlay_hints(source)
117111
inlay_hints = InlayHints.find(SyntaxTree.parse(source))
118112
serialize = ->(position, text) { { position: position, text: text } }

lib/syntax_tree/language_server/inlay_hints.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ def visit(node)
3838
#
3939
def visit_assign(node)
4040
parentheses(node.location) if stack[-2].is_a?(Params)
41+
super
4142
end
4243

4344
# Adds parentheses around binary expressions to make it clear which
@@ -57,6 +58,8 @@ def visit_binary(node)
5758
parentheses(node.location)
5859
else
5960
end
61+
62+
super
6063
end
6164

6265
# Adds parentheses around ternary operators contained within certain
@@ -70,9 +73,13 @@ def visit_binary(node)
7073
# a ? b : ₍c ? d : e₎
7174
#
7275
def visit_if_op(node)
73-
if stack[-2] in Assign | Binary | IfOp | OpAssign
76+
case stack[-2]
77+
in Assign | Binary | IfOp | OpAssign
7478
parentheses(node.location)
79+
else
7580
end
81+
82+
super
7683
end
7784

7885
# Adds the implicitly rescued StandardError into a bare rescue clause. For
@@ -92,6 +99,8 @@ def visit_rescue(node)
9299
if node.exception.nil?
93100
after[node.location.start_char + "rescue".length] << " StandardError"
94101
end
102+
103+
super
95104
end
96105

97106
# Adds parentheses around unary statements using the - operator that are
@@ -107,6 +116,8 @@ def visit_unary(node)
107116
if stack[-2].is_a?(Binary) && (node.operator == "-")
108117
parentheses(node.location)
109118
end
119+
120+
super
110121
end
111122

112123
def self.find(program)

lib/syntax_tree/node.rb

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2129,11 +2129,13 @@ def format(q)
21292129
#
21302130
# break
21312131
#
2132-
in [Paren[
2133-
contents: {
2134-
body: [ArrayLiteral[contents: { parts: [_, _, *] }] => array]
2135-
}
2136-
]]
2132+
in [
2133+
Paren[
2134+
contents: {
2135+
body: [ArrayLiteral[contents: { parts: [_, _, *] }] => array]
2136+
}
2137+
]
2138+
]
21372139
# Here we have a single argument that is a set of parentheses wrapping
21382140
# an array literal that has at least 2 elements. We're going to print
21392141
# the contents of the array directly. This would be like if we had:
@@ -5472,12 +5474,14 @@ def format_flat(q)
54725474
q.format(predicate)
54735475
q.text(" ?")
54745476

5475-
q.breakable
5476-
q.format(truthy)
5477-
q.text(" :")
5477+
q.indent do
5478+
q.breakable
5479+
q.format(truthy)
5480+
q.text(" :")
54785481

5479-
q.breakable
5480-
q.format(falsy)
5482+
q.breakable
5483+
q.format(falsy)
5484+
end
54815485
end
54825486
end
54835487

lib/syntax_tree/parser.rb

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -548,13 +548,6 @@ def on_aryptn(constant, requireds, rest, posts)
548548
parts[0].location.to(parts[-1].location)
549549
end
550550

551-
# If there's the optional then keyword, then we'll delete that and use it
552-
# as the end bounds of the location.
553-
if (token = find_token(Kw, "then", consume: false))
554-
tokens.delete(token)
555-
location = location.to(token.location)
556-
end
557-
558551
# If there is a plain *, then we're going to fix up the location of it
559552
# here because it currently doesn't have anything to use for its precise
560553
# location. If we hit a comma, then we've gone too far.
@@ -1698,12 +1691,6 @@ def on_hshptn(constant, keywords, keyword_rest)
16981691
end
16991692
end
17001693

1701-
# Delete the optional then keyword
1702-
if (token = find_token(Kw, "then", consume: false))
1703-
parts << token
1704-
tokens.delete(token)
1705-
end
1706-
17071694
HshPtn.new(
17081695
constant: constant,
17091696
keywords: keywords || [],
@@ -3013,6 +3000,11 @@ def on_stmts_new
30133000
# (StringEmbExpr | StringDVar | TStringContent) part
30143001
# ) -> StringContent
30153002
def on_string_add(string, part)
3003+
# Due to some eccentricities in how ripper works, you need this here in
3004+
# case you have a syntax error with an embedded expression that doesn't
3005+
# finish, as in: "#{"
3006+
return string if part.is_a?(String)
3007+
30163008
location =
30173009
string.parts.any? ? string.location.to(part.location) : part.location
30183010

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
# frozen_string_literal: true
22

3-
require "syntax_tree/formatter/single_quotes"
4-
SyntaxTree::Formatter.prepend(SyntaxTree::Formatter::SingleQuotes)
3+
SyntaxTree::Formatter::OPTIONS[:quote] = "'"
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
# frozen_string_literal: true
22

3-
require "syntax_tree/formatter/trailing_comma"
4-
SyntaxTree::Formatter.prepend(SyntaxTree::Formatter::TrailingComma)
3+
SyntaxTree::Formatter::OPTIONS[:trailing_comma] = true

test/cli_test.rb

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,41 @@ def test_generic_error
142142
end
143143
end
144144

145+
def test_plugins
146+
Dir.mktmpdir do |directory|
147+
Dir.mkdir(File.join(directory, "syntax_tree"))
148+
$:.unshift(directory)
149+
150+
File.write(
151+
File.join(directory, "syntax_tree", "plugin.rb"),
152+
"puts 'Hello, world!'"
153+
)
154+
result = run_cli("format", "--plugins=plugin")
155+
156+
assert_equal("Hello, world!\ntest\n", result.stdio)
157+
end
158+
end
159+
160+
def test_language_server
161+
prev_stdin = $stdin
162+
prev_stdout = $stdout
163+
164+
request = { method: "shutdown" }.merge(jsonrpc: "2.0").to_json
165+
$stdin =
166+
StringIO.new("Content-Length: #{request.bytesize}\r\n\r\n#{request}")
167+
$stdout = StringIO.new
168+
169+
assert_equal(0, SyntaxTree::CLI.run(["lsp"]))
170+
ensure
171+
$stdin = prev_stdin
172+
$stdout = prev_stdout
173+
end
174+
145175
private
146176

147177
Result = Struct.new(:status, :stdio, :stderr, keyword_init: true)
148178

149-
def run_cli(command, file: nil)
179+
def run_cli(command, *args, file: nil)
150180
if file.nil?
151181
file = Tempfile.new(%w[test- .rb])
152182
file.puts("test")
@@ -156,7 +186,7 @@ def run_cli(command, file: nil)
156186

157187
status = nil
158188
stdio, stderr =
159-
capture_io { status = SyntaxTree::CLI.run([command, file.path]) }
189+
capture_io { status = SyntaxTree::CLI.run([command, *args, file.path]) }
160190

161191
Result.new(status: status, stdio: stdio, stderr: stderr)
162192
ensure

test/fixtures/aryptn.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,22 @@
44
end
55
%
66
case foo
7+
in [] then
8+
end
9+
-
10+
case foo
11+
in []
12+
end
13+
%
14+
case foo
15+
in * then
16+
end
17+
-
18+
case foo
19+
in [*]
20+
end
21+
%
22+
case foo
723
in _, _
824
end
925
-

test/fixtures/call.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
%
22
foo.bar
33
%
4+
foo.bar(baz)
5+
%
46
foo.()
57
%
68
foo::()
@@ -21,3 +23,40 @@
2123
.barrrrrrrrrrrrrrrrrrr {}
2224
.bazzzzzzzzzzzzzzzzzzzzzzzzzz
2325
.quxxxxxxxxx
26+
%
27+
foo. # comment
28+
bar
29+
%
30+
foo
31+
.bar
32+
.baz # comment
33+
.qux
34+
.quux
35+
%
36+
foo
37+
.bar
38+
.baz.
39+
# comment
40+
qux
41+
.quux
42+
%
43+
{ a: 1, b: 2 }.fooooooooooooooooo.barrrrrrrrrrrrrrrrrrr.bazzzzzzzzzzzz.quxxxxxxxxxxxx
44+
-
45+
{ a: 1, b: 2 }.fooooooooooooooooo
46+
.barrrrrrrrrrrrrrrrrrr
47+
.bazzzzzzzzzzzz
48+
.quxxxxxxxxxxxx
49+
%
50+
fooooooooooooooooo.barrrrrrrrrrrrrrrrrrr.bazzzzzzzzzzzz.quxxxxxxxxxxxx.each { block }
51+
-
52+
fooooooooooooooooo.barrrrrrrrrrrrrrrrrrr.bazzzzzzzzzzzz.quxxxxxxxxxxxx.each do
53+
block
54+
end
55+
%
56+
foo.bar.baz.each do
57+
block1
58+
block2
59+
end
60+
%
61+
a b do
62+
end.c d

test/fixtures/command_call.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@
3232
foo.
3333
# comment
3434
bar baz
35+
%
36+
foo.bar baz ? qux : qaz

test/fixtures/do_block.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,15 @@
1414
foo :bar do
1515
baz
1616
end
17+
%
18+
sig do
19+
override.params(contacts: Contact::ActiveRecord_Relation).returns(
20+
Customer::ActiveRecord_Relation
21+
)
22+
end
23+
-
24+
sig do
25+
override
26+
.params(contacts: Contact::ActiveRecord_Relation)
27+
.returns(Customer::ActiveRecord_Relation)
28+
end

0 commit comments

Comments
 (0)