summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSchneems <[email protected]>2024-11-14 18:54:46 -0600
committergit <[email protected]>2024-11-15 01:31:26 +0000
commit226cfda3069c76c094d294a68585b5772fcc730a (patch)
tree8de78ddbce11b56d96703d0055c4894ddf4fea41
parent51666c827b5aa9289113699670cbd6910ea2b3b1 (diff)
[ruby/syntax_suggest] Fix missing line break due to puts logic
In #225 it was reported that the output looks incorrect: ``` $ cat /tmp/4a71c7e417cc9eac0971e3a2519b295c/scratch.rb def x.y.z end $ ruby /tmp/4a71c7e417cc9eac0971e3a2519b295c/scratch.rb /tmp/4a71c7e417cc9eac0971e3a2519b295c/scratch.rb: --> /tmp/4a71c7e417cc9eac0971e3a2519b295c/scratch.rb expected a delimiter to close the parametersunexpected '.', ignoring it > 1 def x.y.z > 2 end ``` Specifically: ``` expected a delimiter to close the parametersunexpected '.', ignoring it ``` However this does not show up when executing the debug executable: ``` $ bin/bundle exec exe/syntax_suggest /tmp/4a71c7e417cc9eac0971e3a2519b295c/scratch.rb --> /tmp/4a71c7e417cc9eac0971e3a2519b295c/scratch.rb expected a delimiter to close the parameters unexpected '.', ignoring it > 1 def x.y.z > 2 end ``` This is because `exe/syntax_suggest` uses STDOUT.puts while calling `ruby` with the filename uses a fake IO object represented by MiniStringIO. This class was incorrectly not adding a newline to the end of the print. The fix was to move the class to it's own file where it can be tested and then fix the behavior. close https://github.com/ruby/syntax_suggest/pull/225 https://github.com/ruby/syntax_suggest/commit/d2ecd94a3b Co-authored-by: Andy Yong <[email protected]>
-rw-r--r--lib/syntax_suggest/api.rb1
-rw-r--r--lib/syntax_suggest/core_ext.rb18
-rw-r--r--lib/syntax_suggest/mini_stringio.rb24
-rw-r--r--spec/syntax_suggest/unit/mini_stringio_spec.rb25
4 files changed, 50 insertions, 18 deletions
diff --git a/lib/syntax_suggest/api.rb b/lib/syntax_suggest/api.rb
index 65660ec5e5..46c9c8adac 100644
--- a/lib/syntax_suggest/api.rb
+++ b/lib/syntax_suggest/api.rb
@@ -227,6 +227,7 @@ require_relative "lex_all"
require_relative "code_line"
require_relative "code_block"
require_relative "block_expand"
+require_relative "mini_stringio"
require_relative "priority_queue"
require_relative "unvisited_lines"
require_relative "around_block_scan"
diff --git a/lib/syntax_suggest/core_ext.rb b/lib/syntax_suggest/core_ext.rb
index c299627bb7..94f57ba605 100644
--- a/lib/syntax_suggest/core_ext.rb
+++ b/lib/syntax_suggest/core_ext.rb
@@ -3,24 +3,6 @@
# Ruby 3.2+ has a cleaner way to hook into Ruby that doesn't use `require`
if SyntaxError.method_defined?(:detailed_message)
module SyntaxSuggest
- # Mini String IO [Private]
- #
- # Acts like a StringIO with reduced API, but without having to require that
- # class.
- class MiniStringIO
- def initialize(isatty: $stderr.isatty)
- @string = +""
- @isatty = isatty
- end
-
- attr_reader :isatty
- def puts(value = $/, **)
- @string << value
- end
-
- attr_reader :string
- end
-
# SyntaxSuggest.module_for_detailed_message [Private]
#
# Used to monkeypatch SyntaxError via Module.prepend
diff --git a/lib/syntax_suggest/mini_stringio.rb b/lib/syntax_suggest/mini_stringio.rb
new file mode 100644
index 0000000000..ee5192ba90
--- /dev/null
+++ b/lib/syntax_suggest/mini_stringio.rb
@@ -0,0 +1,24 @@
+module SyntaxSuggest
+ # Mini String IO [Private]
+ #
+ # Acts like a StringIO with reduced API, but without having to require that
+ # class.
+ class MiniStringIO
+ EMPTY_ARG = Object.new
+
+ def initialize(isatty: $stderr.isatty)
+ @string = +""
+ @isatty = isatty
+ end
+
+ attr_reader :isatty
+ def puts(value = EMPTY_ARG, **)
+ if !value.equal?(EMPTY_ARG)
+ @string << value
+ end
+ @string << $/
+ end
+
+ attr_reader :string
+ 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